AzeorthCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
WorldSession Class Reference

Player session in the World. More...

#include <WorldSession.h>

Classes

class  DosProtection
 

Public Member Functions

 WorldSession (uint32 id, std::string &&name, std::shared_ptr< WorldSocket > sock, AccountTypes sec, uint8 expansion, time_t mute_time, LocaleConstant locale, uint32 recruiter, bool isARecruiter, bool skipQueue, uint32 TotalTime)
 WorldSession constructor. More...
 
 ~WorldSession ()
 WorldSession destructor. More...
 
bool PlayerLoading () const
 
bool PlayerLogout () const
 
bool PlayerLogoutWithSave () const
 
void ReadAddonsInfo (ByteBuffer &data)
 
void SendAddonsInfo ()
 
void ReadMovementInfo (WorldPacket &data, MovementInfo *mi)
 
void WriteMovementInfo (WorldPacket *data, MovementInfo *mi)
 
void SendPacket (WorldPacket const *packet)
 Send a packet to the client. More...
 
void SendNotification (const char *format,...) ATTR_PRINTF(2
 
void void SendNotification (uint32 string_id,...)
 
void SendPetNameInvalid (uint32 error, std::string const &name, DeclinedName *declinedName)
 
void SendPartyResult (PartyOperation operation, std::string const &member, PartyResult res, uint32 val=0)
 
void SendAreaTriggerMessage (const char *Text,...) ATTR_PRINTF(2
 
void void SendSetPhaseShift (uint32 phaseShift)
 
void SendQueryTimeResponse ()
 
void SendAuthResponse (uint8 code, bool shortForm, uint32 queuePos=0)
 
void SendClientCacheVersion (uint32 version)
 
AccountTypes GetSecurity () const
 
bool CanSkipQueue () const
 
uint32 GetAccountId () const
 
PlayerGetPlayer () const
 
std::string const & GetPlayerName () const
 
std::string GetPlayerInfo () const
 
uint32 GetCurrentVendor () const
 
void SetCurrentVendor (uint32 vendorEntry)
 
ObjectGuid::LowType GetGuidLow () const
 Get player guid if available. Use for logging purposes only. More...
 
void SetSecurity (AccountTypes security)
 
std::string const & GetRemoteAddress ()
 
void SetPlayer (Player *player)
 
uint8 Expansion () const
 
void SetTotalTime (uint32 TotalTime)
 
uint32 GetTotalTime () const
 
void InitWarden (SessionKey const &, std::string const &os)
 
void SetInQueue (bool state)
 Session in auth.queue currently. More...
 
bool isLogingOut () const
 Is the user engaged in a log out process? More...
 
void SetLogoutStartTime (time_t requestTime)
 Engage the logout process for the user. More...
 
bool ShouldLogOut (time_t currTime) const
 Is logout cooldown expired? More...
 
void LogoutPlayer (bool save)
 Log the player out More...
 
void KickPlayer (bool setKicked=true)
 
void KickPlayer (std::string const &reason, bool setKicked=true)
 Kick a player out of the World. More...
 
bool ValidateHyperlinksAndMaybeKick (std::string_view str)
 
bool DisallowHyperlinksAndMaybeKick (std::string_view str)
 
void QueuePacket (WorldPacket *new_packet)
 Add an incoming packet to the queue. More...
 
bool Update (uint32 diff, PacketFilter &updater)
 Update the WorldSession (triggered by World update) More...
 
void SendAuthWaitQueue (uint32 position)
 Handle the authentication waiting queue (to be completed) More...
 
void SendNameQueryOpcode (ObjectGuid guid)
 
void SendTrainerList (ObjectGuid guid)
 
void SendTrainerList (ObjectGuid guid, std::string const &strTitle)
 
void SendListInventory (ObjectGuid guid, uint32 vendorEntry=0)
 
void SendShowBank (ObjectGuid guid)
 
bool CanOpenMailBox (ObjectGuid guid)
 
void SendShowMailBox (ObjectGuid guid)
 
void SendTabardVendorActivate (ObjectGuid guid)
 
void SendSpiritResurrect ()
 
void SendBindPoint (Creature *npc)
 
void SendAttackStop (Unit const *enemy)
 
void SendBattleGroundList (ObjectGuid guid, BattlegroundTypeId bgTypeId=BATTLEGROUND_RB)
 
void SendTradeStatus (TradeStatus status)
 
void SendUpdateTrade (bool trader_data=true)
 
void SendCancelTrade ()
 
void SendPetitionQueryOpcode (ObjectGuid petitionguid)
 
void HandleClientCastFlags (WorldPacket &recvPacket, uint8 castFlags, SpellCastTargets &targets)
 
void SendPetNameQuery (ObjectGuid guid, uint32 petnumber)
 
void SendStablePet (ObjectGuid guid)
 
void SendStablePetCallback (ObjectGuid guid, PreparedQueryResult result)
 
void SendStableResult (uint8 guid)
 
bool CheckStableMaster (ObjectGuid guid)
 
AccountDataGetAccountData (AccountDataType type)
 
void SetAccountData (AccountDataType type, time_t tm, std::string const &data)
 
void SendAccountDataTimes (uint32 mask)
 
void LoadGlobalAccountData ()
 
void LoadAccountData (PreparedQueryResult result, uint32 mask)
 
void LoadTutorialsData ()
 
void SendTutorialsData ()
 
void SaveTutorialsData (CharacterDatabaseTransaction trans)
 
uint32 GetTutorialInt (uint8 index) const
 
void SetTutorialInt (uint8 index, uint32 value)
 
void SendAuctionHello (ObjectGuid guid, Creature *unit)
 
void SendAuctionCommandResult (uint32 auctionId, uint32 Action, uint32 ErrorCode, uint32 bidError=0)
 
void SendAuctionBidderNotification (uint32 location, uint32 auctionId, ObjectGuid bidder, uint32 bidSum, uint32 diff, uint32 item_template)
 
void SendAuctionOwnerNotification (AuctionEntry *auction)
 
void SendEnchantmentLog (ObjectGuid target, ObjectGuid caster, uint32 itemId, uint32 enchantId)
 
void SendItemEnchantTimeUpdate (ObjectGuid Playerguid, ObjectGuid Itemguid, uint32 slot, uint32 Duration)
 
void SendTaxiStatus (ObjectGuid guid)
 
void SendTaxiMenu (Creature *unit)
 
void SendDoFlight (uint32 mountDisplayId, uint32 path, uint32 pathNode=0)
 
bool SendLearnNewTaxiNode (Creature *unit)
 
void SendDiscoverNewTaxiNode (uint32 nodeid)
 
void SendArenaTeamCommandResult (uint32 team_action, std::string const &team, std::string const &player, uint32 error_id=0)
 
void SendNotInArenaTeamPacket (uint8 type)
 
void SendPetitionShowList (ObjectGuid guid)
 
void BuildPartyMemberStatsChangedPacket (Player *player, WorldPacket *data)
 
void DoLootRelease (ObjectGuid lguid)
 
LocaleConstant GetSessionDbcLocale () const
 
LocaleConstant GetSessionDbLocaleIndex () const
 
char const * GetAcoreString (uint32 entry) const
 
uint32 GetLatency () const
 
void SetLatency (uint32 latency)
 
void UpdateTimeOutTime (uint32 diff)
 
void ResetTimeOutTime (bool onlyActive)
 
bool IsConnectionIdle () const
 
uint32 GetRecruiterId () const
 
bool IsARecruiter () const
 
time_t GetCalendarEventCreationCooldown () const
 
void SetCalendarEventCreationCooldown (time_t cooldown)
 
void ResetTimeSync ()
 
void SendTimeSync ()
 
void Handle_NULL (WorldPacket &null)
 
void Handle_EarlyProccess (WorldPacket &recvPacket)
 
void Handle_ServerSide (WorldPacket &recvPacket)
 
void Handle_Deprecated (WorldPacket &recvPacket)
 
void HandleCharEnumOpcode (WorldPacket &recvPacket)
 
void HandleCharDeleteOpcode (WorldPacket &recvPacket)
 
void HandleCharCreateOpcode (WorldPacket &recvPacket)
 
void HandlePlayerLoginOpcode (WorldPacket &recvPacket)
 
void HandleCharEnum (PreparedQueryResult result)
 
void HandlePlayerLoginFromDB (LoginQueryHolder const &holder)
 
void HandlePlayerLoginToCharInWorld (Player *pCurrChar)
 
void HandlePlayerLoginToCharOutOfWorld (Player *pCurrChar)
 
void HandleCharFactionOrRaceChange (WorldPacket &recvData)
 
void HandleCharFactionOrRaceChangeCallback (std::shared_ptr< CharacterFactionChangeInfo > factionChangeInfo, PreparedQueryResult result)
 
void SendCharCreate (ResponseCodes result)
 
void SendCharDelete (ResponseCodes result)
 
void SendCharRename (ResponseCodes result, CharacterRenameInfo const *renameInfo)
 
void SendCharCustomize (ResponseCodes result, CharacterCustomizeInfo const *customizeInfo)
 
void SendCharFactionChange (ResponseCodes result, CharacterFactionChangeInfo const *factionChangeInfo)
 
void SendSetPlayerDeclinedNamesResult (DeclinedNameResult result, ObjectGuid guid)
 
void HandlePlayedTime (WorldPackets::Character::PlayedTimeClient &packet)
 
void HandleMoveUnRootAck (WorldPacket &recvPacket)
 
void HandleMoveRootAck (WorldPacket &recvPacket)
 
void HandleInspectOpcode (WorldPacket &recvPacket)
 
void HandleInspectHonorStatsOpcode (WorldPacket &recvPacket)
 
void HandleMoveWaterWalkAck (WorldPacket &recvPacket)
 
void HandleFeatherFallAck (WorldPacket &recvData)
 
void HandleMoveHoverAck (WorldPacket &recvData)
 
void HandleMountSpecialAnimOpcode (WorldPacket &recvdata)
 
void HandleShowingHelmOpcode (WorldPackets::Character::ShowingHelm &packet)
 
void HandleShowingCloakOpcode (WorldPackets::Character::ShowingCloak &packet)
 
void HandleRepairItemOpcode (WorldPacket &recvPacket)
 
void HandleMoveKnockBackAck (WorldPacket &recvPacket)
 
void HandleMoveTeleportAck (WorldPacket &recvPacket)
 
void HandleForceSpeedChangeAck (WorldPacket &recvData)
 
void HandleRepopRequestOpcode (WorldPacket &recvPacket)
 
void HandleAutostoreLootItemOpcode (WorldPacket &recvPacket)
 
void HandleLootMoneyOpcode (WorldPacket &recvPacket)
 
void HandleLootOpcode (WorldPacket &recvPacket)
 
void HandleLootReleaseOpcode (WorldPacket &recvPacket)
 
void HandleLootMasterGiveOpcode (WorldPacket &recvPacket)
 
void HandleWhoOpcode (WorldPacket &recvPacket)
 
void HandleLogoutRequestOpcode (WorldPackets::Character::LogoutRequest &logoutRequest)
 
void HandlePlayerLogoutOpcode (WorldPackets::Character::PlayerLogout &playerLogout)
 
void HandleLogoutCancelOpcode (WorldPackets::Character::LogoutCancel &logoutCancel)
 
void HandleGMTicketCreateOpcode (WorldPacket &recvPacket)
 
void HandleGMTicketUpdateOpcode (WorldPacket &recvPacket)
 
void HandleGMTicketDeleteOpcode (WorldPacket &recvPacket)
 
void HandleGMTicketGetTicketOpcode (WorldPacket &recvPacket)
 
void HandleGMTicketSystemStatusOpcode (WorldPacket &recvPacket)
 
void HandleGMSurveySubmit (WorldPacket &recvPacket)
 
void HandleReportLag (WorldPacket &recvPacket)
 
void HandleGMResponseResolve (WorldPacket &recvPacket)
 
void HandleTogglePvP (WorldPacket &recvPacket)
 
void HandleZoneUpdateOpcode (WorldPacket &recvPacket)
 
void HandleSetSelectionOpcode (WorldPacket &recvPacket)
 
void HandleStandStateChangeOpcode (WorldPacket &recvPacket)
 
void HandleEmoteOpcode (WorldPackets::Chat::EmoteClient &packet)
 
void HandleContactListOpcode (WorldPacket &recvPacket)
 
void HandleAddFriendOpcode (WorldPacket &recvPacket)
 
void HandleDelFriendOpcode (WorldPacket &recvPacket)
 
void HandleAddIgnoreOpcode (WorldPacket &recvPacket)
 
void HandleDelIgnoreOpcode (WorldPacket &recvPacket)
 
void HandleSetContactNotesOpcode (WorldPacket &recvPacket)
 
void HandleBugOpcode (WorldPacket &recvPacket)
 
void HandleSetAmmoOpcode (WorldPacket &recvPacket)
 
void HandleItemNameQueryOpcode (WorldPacket &recvPacket)
 
void HandleAreaTriggerOpcode (WorldPacket &recvPacket)
 
void HandleSetFactionAtWar (WorldPacket &recvData)
 
void HandleSetFactionCheat (WorldPacket &recvData)
 
void HandleSetWatchedFactionOpcode (WorldPacket &recvData)
 
void HandleSetFactionInactiveOpcode (WorldPacket &recvData)
 
void HandleUpdateAccountData (WorldPacket &recvPacket)
 
void HandleRequestAccountData (WorldPacket &recvPacket)
 
void HandleSetActionButtonOpcode (WorldPacket &recvPacket)
 
void HandleGameObjectUseOpcode (WorldPacket &recPacket)
 
void HandleGameobjectReportUse (WorldPacket &recvPacket)
 
void HandleNameQueryOpcode (WorldPacket &recvPacket)
 
void HandleQueryTimeOpcode (WorldPacket &recvPacket)
 
void HandleCreatureQueryOpcode (WorldPacket &recvPacket)
 Only static data is sent in this packet !!! More...
 
void HandleGameObjectQueryOpcode (WorldPacket &recvPacket)
 Only static data is sent in this packet !!! More...
 
void HandleMoveWorldportAckOpcode (WorldPacket &recvPacket)
 
void HandleMoveWorldportAck ()
 
void HandleMovementOpcodes (WorldPacket &recvPacket)
 
void HandleSetActiveMoverOpcode (WorldPacket &recvData)
 
void HandleMoveNotActiveMover (WorldPacket &recvData)
 
void HandleDismissControlledVehicle (WorldPacket &recvData)
 
void HandleRequestVehicleExit (WorldPacket &recvData)
 
void HandleChangeSeatsOnControlledVehicle (WorldPacket &recvData)
 
void HandleMoveTimeSkippedOpcode (WorldPacket &recvData)
 
void HandleRequestRaidInfoOpcode (WorldPacket &recvData)
 
void HandleBattlefieldStatusOpcode (WorldPacket &recvData)
 
void HandleGroupInviteOpcode (WorldPacket &recvPacket)
 
void HandleGroupAcceptOpcode (WorldPacket &recvPacket)
 
void HandleGroupDeclineOpcode (WorldPacket &recvPacket)
 
void HandleGroupUninviteOpcode (WorldPacket &recvPacket)
 
void HandleGroupUninviteGuidOpcode (WorldPacket &recvPacket)
 
void HandleGroupSetLeaderOpcode (WorldPacket &recvPacket)
 
void HandleGroupDisbandOpcode (WorldPacket &recvPacket)
 
void HandleOptOutOfLootOpcode (WorldPacket &recvData)
 
void HandleLootMethodOpcode (WorldPacket &recvPacket)
 
void HandleLootRoll (WorldPacket &recvData)
 
void HandleRequestPartyMemberStatsOpcode (WorldPacket &recvData)
 
void HandleGroupSwapSubGroupOpcode (WorldPacket &recvData)
 
void HandleRaidTargetUpdateOpcode (WorldPacket &recvData)
 
void HandleRaidReadyCheckOpcode (WorldPacket &recvData)
 
void HandleRaidReadyCheckFinishedOpcode (WorldPacket &recvData)
 
void HandleGroupRaidConvertOpcode (WorldPacket &recvData)
 
void HandleGroupChangeSubGroupOpcode (WorldPacket &recvData)
 
void HandleGroupAssistantLeaderOpcode (WorldPacket &recvData)
 
void HandlePartyAssignmentOpcode (WorldPacket &recvData)
 
void HandlePetitionBuyOpcode (WorldPacket &recvData)
 
void HandlePetitionShowSignOpcode (WorldPacket &recvData)
 
void HandlePetitionQueryOpcode (WorldPacket &recvData)
 
void HandlePetitionRenameOpcode (WorldPacket &recvData)
 
void HandlePetitionSignOpcode (WorldPacket &recvData)
 
void HandlePetitionDeclineOpcode (WorldPacket &recvData)
 
void HandleOfferPetitionOpcode (WorldPacket &recvData)
 
void HandleTurnInPetitionOpcode (WorldPacket &recvData)
 
void HandleGuildQueryOpcode (WorldPackets::Guild::QueryGuildInfo &query)
 
void HandleGuildCreateOpcode (WorldPackets::Guild::GuildCreate &packet)
 
void HandleGuildInviteOpcode (WorldPackets::Guild::GuildInviteByName &packet)
 
void HandleGuildRemoveOpcode (WorldPackets::Guild::GuildOfficerRemoveMember &packet)
 
void HandleGuildAcceptOpcode (WorldPackets::Guild::AcceptGuildInvite &invite)
 
void HandleGuildDeclineOpcode (WorldPackets::Guild::GuildDeclineInvitation &decline)
 
void HandleGuildInfoOpcode (WorldPackets::Guild::GuildGetInfo &packet)
 
void HandleGuildEventLogQueryOpcode (WorldPackets::Guild::GuildEventLogQuery &packet)
 
void HandleGuildRosterOpcode (WorldPackets::Guild::GuildGetRoster &packet)
 
void HandleGuildPromoteOpcode (WorldPackets::Guild::GuildPromoteMember &promote)
 
void HandleGuildDemoteOpcode (WorldPackets::Guild::GuildDemoteMember &demote)
 
void HandleGuildLeaveOpcode (WorldPackets::Guild::GuildLeave &leave)
 
void HandleGuildDisbandOpcode (WorldPackets::Guild::GuildDelete &packet)
 
void HandleGuildLeaderOpcode (WorldPackets::Guild::GuildSetGuildMaster &packet)
 
void HandleGuildMOTDOpcode (WorldPackets::Guild::GuildUpdateMotdText &packet)
 
void HandleGuildSetPublicNoteOpcode (WorldPackets::Guild::GuildSetMemberNote &packet)
 
void HandleGuildSetOfficerNoteOpcode (WorldPackets::Guild::GuildSetMemberNote &packet)
 
void HandleGuildRankOpcode (WorldPackets::Guild::GuildSetRankPermissions &packet)
 
void HandleGuildAddRankOpcode (WorldPackets::Guild::GuildAddRank &packet)
 
void HandleGuildDelRankOpcode (WorldPackets::Guild::GuildDeleteRank &packet)
 
void HandleGuildChangeInfoTextOpcode (WorldPackets::Guild::GuildUpdateInfoText &packet)
 
void HandleSaveGuildEmblemOpcode (WorldPackets::Guild::SaveGuildEmblem &packet)
 
void HandleTaxiNodeStatusQueryOpcode (WorldPacket &recvPacket)
 
void HandleTaxiQueryAvailableNodes (WorldPacket &recvPacket)
 
void HandleActivateTaxiOpcode (WorldPacket &recvPacket)
 
void HandleActivateTaxiExpressOpcode (WorldPacket &recvPacket)
 
void HandleMoveSplineDoneOpcode (WorldPacket &recvPacket)
 
void SendActivateTaxiReply (ActivateTaxiReply reply)
 
void HandleTabardVendorActivateOpcode (WorldPacket &recvPacket)
 
void HandleTrainerListOpcode (WorldPacket &recvPacket)
 
void HandleTrainerBuySpellOpcode (WorldPacket &recvPacket)
 
void HandlePetitionShowListOpcode (WorldPacket &recvPacket)
 
void HandleGossipHelloOpcode (WorldPacket &recvPacket)
 
void HandleGossipSelectOptionOpcode (WorldPacket &recvPacket)
 
void HandleSpiritHealerActivateOpcode (WorldPacket &recvPacket)
 
void HandleNpcTextQueryOpcode (WorldPacket &recvPacket)
 
void HandleBinderActivateOpcode (WorldPacket &recvPacket)
 
void HandleListStabledPetsOpcode (WorldPacket &recvPacket)
 
void HandleStablePet (WorldPacket &recvPacket)
 
void HandleUnstablePet (WorldPacket &recvPacket)
 
void HandleBuyStableSlot (WorldPacket &recvPacket)
 
void HandleStableRevivePet (WorldPacket &recvPacket)
 
void HandleStableSwapPet (WorldPacket &recvPacket)
 
void HandleOpenWrappedItemCallback (uint8 bagIndex, uint8 slot, ObjectGuid::LowType itemLowGUID, PreparedQueryResult result)
 
void HandleLoadActionsSwitchSpec (PreparedQueryResult result)
 
void HandleCharacterAuraFrozen (PreparedQueryResult result)
 
void HandleDuelAcceptedOpcode (WorldPacket &recvPacket)
 
void HandleDuelCancelledOpcode (WorldPacket &recvPacket)
 
void HandleAcceptTradeOpcode (WorldPacket &recvPacket)
 
void HandleBeginTradeOpcode (WorldPacket &recvPacket)
 
void HandleBusyTradeOpcode (WorldPacket &recvPacket)
 
void HandleCancelTradeOpcode (WorldPacket &recvPacket)
 
void HandleClearTradeItemOpcode (WorldPacket &recvPacket)
 
void HandleIgnoreTradeOpcode (WorldPacket &recvPacket)
 
void HandleInitiateTradeOpcode (WorldPacket &recvPacket)
 
void HandleSetTradeGoldOpcode (WorldPacket &recvPacket)
 
void HandleSetTradeItemOpcode (WorldPacket &recvPacket)
 
void HandleUnacceptTradeOpcode (WorldPacket &recvPacket)
 
void HandleAuctionHelloOpcode (WorldPacket &recvPacket)
 
void HandleAuctionListItems (WorldPacket &recvData)
 
void HandleAuctionListBidderItems (WorldPacket &recvData)
 
void HandleAuctionSellItem (WorldPacket &recvData)
 
void HandleAuctionRemoveItem (WorldPacket &recvData)
 
void HandleAuctionListOwnerItems (WorldPacket &recvData)
 
void HandleAuctionListOwnerItemsEvent (ObjectGuid creatureGuid)
 
void HandleAuctionPlaceBid (WorldPacket &recvData)
 
void HandleAuctionListPendingSales (WorldPacket &recvData)
 
void HandleBankerActivateOpcode (WorldPacket &recvData)
 
void HandleAutoBankItemOpcode (WorldPackets::Bank::AutoBankItem &packet)
 
void HandleAutoStoreBankItemOpcode (WorldPackets::Bank::AutoStoreBankItem &packet)
 
void HandleBuyBankSlotOpcode (WorldPackets::Bank::BuyBankSlot &buyBankSlot)
 
void HandleGetMailList (WorldPacket &recvData)
 
void HandleSendMail (WorldPacket &recvData)
 
void HandleMailTakeMoney (WorldPacket &recvData)
 
void HandleMailTakeItem (WorldPacket &recvData)
 
void HandleMailMarkAsRead (WorldPacket &recvData)
 
void HandleMailReturnToSender (WorldPacket &recvData)
 
void HandleMailDelete (WorldPacket &recvData)
 
void HandleItemTextQuery (WorldPacket &recvData)
 
void HandleMailCreateTextItem (WorldPacket &recvData)
 
void HandleQueryNextMailTime (WorldPacket &recvData)
 
void HandleCancelChanneling (WorldPacket &recvData)
 
void HandleSplitItemOpcode (WorldPacket &recvPacket)
 
void HandleSwapInvItemOpcode (WorldPacket &recvPacket)
 
void HandleDestroyItemOpcode (WorldPacket &recvPacket)
 
void HandleAutoEquipItemOpcode (WorldPacket &recvPacket)
 
void HandleItemQuerySingleOpcode (WorldPacket &recvPacket)
 
void HandleSellItemOpcode (WorldPacket &recvPacket)
 
void HandleBuyItemInSlotOpcode (WorldPacket &recvPacket)
 
void HandleBuyItemOpcode (WorldPacket &recvPacket)
 
void HandleListInventoryOpcode (WorldPacket &recvPacket)
 
void HandleAutoStoreBagItemOpcode (WorldPacket &recvPacket)
 
void HandleReadItem (WorldPacket &recvPacket)
 
void HandleAutoEquipItemSlotOpcode (WorldPacket &recvPacket)
 
void HandleSwapItem (WorldPacket &recvPacket)
 
void HandleBuybackItem (WorldPacket &recvPacket)
 
void HandleWrapItemOpcode (WorldPacket &recvPacket)
 
void HandleAttackSwingOpcode (WorldPacket &recvPacket)
 
void HandleAttackStopOpcode (WorldPacket &recvPacket)
 
void HandleSetSheathedOpcode (WorldPackets::Combat::SetSheathed &packet)
 
void HandleUseItemOpcode (WorldPacket &recvPacket)
 
void HandleOpenItemOpcode (WorldPacket &recvPacket)
 
void HandleCastSpellOpcode (WorldPacket &recvPacket)
 
void HandleCancelCastOpcode (WorldPacket &recvPacket)
 
void HandleCancelAuraOpcode (WorldPacket &recvPacket)
 
void HandleCancelGrowthAuraOpcode (WorldPacket &recvPacket)
 
void HandleCancelAutoRepeatSpellOpcode (WorldPacket &recvPacket)
 
void HandleLearnTalentOpcode (WorldPacket &recvPacket)
 
void HandleLearnPreviewTalents (WorldPacket &recvPacket)
 
void HandleTalentWipeConfirmOpcode (WorldPacket &recvPacket)
 
void HandleUnlearnSkillOpcode (WorldPacket &recvPacket)
 
void HandleQuestgiverStatusQueryOpcode (WorldPacket &recvPacket)
 
void HandleQuestgiverStatusMultipleQuery (WorldPacket &recvPacket)
 
void HandleQuestgiverHelloOpcode (WorldPacket &recvPacket)
 
void HandleQuestgiverAcceptQuestOpcode (WorldPacket &recvPacket)
 
void HandleQuestgiverQueryQuestOpcode (WorldPacket &recvPacket)
 
void HandleQuestgiverChooseRewardOpcode (WorldPacket &recvPacket)
 
void HandleQuestgiverRequestRewardOpcode (WorldPacket &recvPacket)
 
void HandleQuestQueryOpcode (WorldPacket &recvPacket)
 
void HandleQuestgiverCancel (WorldPacket &recvData)
 
void HandleQuestLogSwapQuest (WorldPacket &recvData)
 
void HandleQuestLogRemoveQuest (WorldPacket &recvData)
 
void HandleQuestConfirmAccept (WorldPacket &recvData)
 
void HandleQuestgiverCompleteQuest (WorldPacket &recvData)
 
void HandleQuestgiverQuestAutoLaunch (WorldPacket &recvPacket)
 
void HandlePushQuestToParty (WorldPacket &recvPacket)
 
void HandleQuestPushResult (WorldPacket &recvPacket)
 
void HandleMessagechatOpcode (WorldPacket &recvPacket)
 
void SendPlayerNotFoundNotice (std::string const &name)
 
void SendPlayerAmbiguousNotice (std::string const &name)
 
void SendWrongFactionNotice ()
 
void SendChatRestrictedNotice (ChatRestrictionType restriction)
 
void HandleTextEmoteOpcode (WorldPacket &recvPacket)
 
void HandleChatIgnoredOpcode (WorldPacket &recvPacket)
 
void HandleReclaimCorpseOpcode (WorldPacket &recvPacket)
 
void HandleCorpseQueryOpcode (WorldPacket &recvPacket)
 
void HandleCorpseMapPositionQuery (WorldPacket &recvPacket)
 
void HandleResurrectResponseOpcode (WorldPacket &recvPacket)
 
void HandleSummonResponseOpcode (WorldPacket &recvData)
 
void HandleJoinChannel (WorldPacket &recvPacket)
 
void HandleLeaveChannel (WorldPacket &recvPacket)
 
void HandleChannelList (WorldPacket &recvPacket)
 
void HandleChannelPassword (WorldPacket &recvPacket)
 
void HandleChannelSetOwner (WorldPacket &recvPacket)
 
void HandleChannelOwner (WorldPacket &recvPacket)
 
void HandleChannelModerator (WorldPacket &recvPacket)
 
void HandleChannelUnmoderator (WorldPacket &recvPacket)
 
void HandleChannelMute (WorldPacket &recvPacket)
 
void HandleChannelUnmute (WorldPacket &recvPacket)
 
void HandleChannelInvite (WorldPacket &recvPacket)
 
void HandleChannelKick (WorldPacket &recvPacket)
 
void HandleChannelBan (WorldPacket &recvPacket)
 
void HandleChannelUnban (WorldPacket &recvPacket)
 
void HandleChannelAnnouncements (WorldPacket &recvPacket)
 
void HandleChannelModerateOpcode (WorldPacket &recvPacket)
 
void HandleChannelDeclineInvite (WorldPacket &recvPacket)
 
void HandleChannelDisplayListQuery (WorldPacket &recvPacket)
 
void HandleGetChannelMemberCount (WorldPacket &recvPacket)
 
void HandleSetChannelWatch (WorldPacket &recvPacket)
 
void HandleClearChannelWatch (WorldPacket &recvPacket)
 
void HandleCompleteCinematic (WorldPacket &recvPacket)
 
void HandleNextCinematicCamera (WorldPacket &recvPacket)
 
void HandlePageTextQueryOpcode (WorldPacket &recvPacket)
 Only static data is sent in this packet !!! More...
 
void HandleTutorialFlag (WorldPacket &recvData)
 
void HandleTutorialClear (WorldPacket &recvData)
 
void HandleTutorialReset (WorldPacket &recvData)
 
void HandlePetAction (WorldPacket &recvData)
 
void HandlePetStopAttack (WorldPackets::Pet::PetStopAttack &packet)
 
void HandlePetActionHelper (Unit *pet, ObjectGuid guid1, uint32 spellid, uint16 flag, ObjectGuid guid2)
 
void HandlePetNameQuery (WorldPacket &recvData)
 
void HandlePetSetAction (WorldPacket &recvData)
 
void HandlePetAbandon (WorldPackets::Pet::PetAbandon &packet)
 
void HandlePetRename (WorldPacket &recvData)
 
void HandlePetCancelAuraOpcode (WorldPacket &recvPacket)
 
void HandlePetSpellAutocastOpcode (WorldPackets::Pet::PetSpellAutocast &packet)
 
void HandlePetCastSpellOpcode (WorldPacket &recvPacket)
 
void HandlePetLearnTalent (WorldPacket &recvPacket)
 
void HandleLearnPreviewTalentsPet (WorldPacket &recvPacket)
 
void HandleSetActionBarToggles (WorldPacket &recvData)
 
void HandleCharRenameOpcode (WorldPacket &recvData)
 
void HandleCharRenameCallBack (std::shared_ptr< CharacterRenameInfo > renameInfo, PreparedQueryResult result)
 
void HandleSetPlayerDeclinedNames (WorldPacket &recvData)
 
void HandleTotemDestroyed (WorldPackets::Totem::TotemDestroyed &totemDestroyed)
 
void HandleDismissCritter (WorldPackets::Pet::DismissCritter &dismissCritter)
 
void HandleBattlemasterHelloOpcode (WorldPacket &recvData)
 
void HandleBattlemasterJoinOpcode (WorldPacket &recvData)
 
void HandleBattlegroundPlayerPositionsOpcode (WorldPacket &recvData)
 
void HandlePVPLogDataOpcode (WorldPacket &recvData)
 
void HandleBattleFieldPortOpcode (WorldPacket &recvData)
 
void HandleBattlefieldListOpcode (WorldPacket &recvData)
 
void HandleBattlefieldLeaveOpcode (WorldPacket &recvData)
 
void HandleBattlemasterJoinArena (WorldPacket &recvData)
 
void HandleReportPvPAFK (WorldPacket &recvData)
 
void HandleWardenDataOpcode (WorldPacket &recvData)
 
void HandleWorldTeleportOpcode (WorldPacket &recvData)
 
void HandleMinimapPingOpcode (WorldPacket &recvData)
 
void HandleRandomRollOpcode (WorldPackets::Misc::RandomRollClient &packet)
 
void HandleFarSightOpcode (WorldPacket &recvData)
 
void HandleSetDungeonDifficultyOpcode (WorldPacket &recvData)
 
void HandleSetRaidDifficultyOpcode (WorldPacket &recvData)
 
void HandleMoveSetCanFlyAckOpcode (WorldPacket &recvData)
 
void HandleSetTitleOpcode (WorldPacket &recvData)
 
void HandleRealmSplitOpcode (WorldPacket &recvData)
 
void HandleTimeSyncResp (WorldPacket &recvData)
 
void HandleWhoisOpcode (WorldPacket &recvData)
 
void HandleResetInstancesOpcode (WorldPacket &recvData)
 
void HandleHearthAndResurrect (WorldPacket &recvData)
 
void HandleInstanceLockResponse (WorldPacket &recvPacket)
 
void HandleUpdateMissileTrajectory (WorldPacket &recvPacket)
 
void SendBfInvitePlayerToWar (uint32 battleId, uint32 zoneId, uint32 time)
 
void SendBfInvitePlayerToQueue (uint32 battleId)
 
void SendBfQueueInviteResponse (uint32 battleId, uint32 zoneId, bool canQueue=true, bool full=false)
 
void SendBfEntered (uint32 battleId)
 
void SendBfLeaveMessage (uint32 battleId, BFLeaveReason reason=BF_LEAVE_REASON_EXITED)
 
void HandleBfQueueInviteResponse (WorldPacket &recvData)
 
void HandleBfEntryInviteResponse (WorldPacket &recvData)
 
void HandleBfExitRequest (WorldPacket &recvData)
 
void HandleLfgSetCommentOpcode (WorldPacket &recvData)
 
void HandleLfgPlayerLockInfoRequestOpcode (WorldPacket &recvData)
 
void HandleLfgPartyLockInfoRequestOpcode (WorldPacket &recvData)
 
void HandleLfgJoinOpcode (WorldPackets::LFG::LFGJoin &lfgJoin)
 
void HandleLfgLeaveOpcode (WorldPackets::LFG::LFGLeave &lfgleave)
 
void HandleLfgSetRolesOpcode (WorldPacket &recvData)
 
void HandleLfgProposalResultOpcode (WorldPacket &recvData)
 
void HandleLfgSetBootVoteOpcode (WorldPacket &recvData)
 
void HandleLfgTeleportOpcode (WorldPacket &recvData)
 
void HandleLfrSearchJoinOpcode (WorldPacket &recvData)
 
void HandleLfrSearchLeaveOpcode (WorldPacket &recvData)
 
void HandleLfgGetStatus (WorldPacket &recvData)
 
void SendLfgUpdatePlayer (lfg::LfgUpdateData const &updateData)
 
void SendLfgUpdateParty (lfg::LfgUpdateData const &updateData)
 
void SendLfgRoleChosen (ObjectGuid guid, uint8 roles)
 
void SendLfgRoleCheckUpdate (lfg::LfgRoleCheck const &pRoleCheck)
 
void SendLfgLfrList (bool update)
 
void SendLfgJoinResult (lfg::LfgJoinResultData const &joinData)
 
void SendLfgQueueStatus (lfg::LfgQueueStatusData const &queueData)
 
void SendLfgPlayerReward (lfg::LfgPlayerRewardData const &lfgPlayerRewardData)
 
void SendLfgBootProposalUpdate (lfg::LfgPlayerBoot const &boot)
 
void SendLfgUpdateProposal (lfg::LfgProposal const &proposal)
 
void SendLfgDisabled ()
 
void SendLfgOfferContinue (uint32 dungeonEntry)
 
void SendLfgTeleportError (uint8 err)
 
void HandleInspectArenaTeamsOpcode (WorldPacket &recvData)
 
void HandleArenaTeamQueryOpcode (WorldPacket &recvData)
 
void HandleArenaTeamRosterOpcode (WorldPacket &recvData)
 
void HandleArenaTeamInviteOpcode (WorldPacket &recvData)
 
void HandleArenaTeamAcceptOpcode (WorldPacket &recvData)
 
void HandleArenaTeamDeclineOpcode (WorldPacket &recvData)
 
void HandleArenaTeamLeaveOpcode (WorldPacket &recvData)
 
void HandleArenaTeamRemoveOpcode (WorldPacket &recvData)
 
void HandleArenaTeamDisbandOpcode (WorldPacket &recvData)
 
void HandleArenaTeamLeaderOpcode (WorldPacket &recvData)
 
void HandleAreaSpiritHealerQueryOpcode (WorldPacket &recvData)
 
void HandleAreaSpiritHealerQueueOpcode (WorldPacket &recvData)
 
void HandleCancelMountAuraOpcode (WorldPacket &recvData)
 
void HandleSelfResOpcode (WorldPacket &recvData)
 
void HandleComplainOpcode (WorldPacket &recvData)
 
void HandleRequestPetInfo (WorldPackets::Pet::RequestPetInfo &packet)
 
void HandleSocketOpcode (WorldPacket &recvData)
 
void HandleCancelTempEnchantmentOpcode (WorldPacket &recvData)
 
void HandleItemRefundInfoRequest (WorldPacket &recvData)
 
void HandleItemRefund (WorldPacket &recvData)
 
void HandleChannelVoiceOnOpcode (WorldPacket &recvData)
 
void HandleVoiceSessionEnableOpcode (WorldPacket &recvData)
 
void HandleSetActiveVoiceChannel (WorldPacket &recvData)
 
void HandleSetTaxiBenchmarkOpcode (WorldPacket &recvData)
 
void HandleGuildPermissions (WorldPackets::Guild::GuildPermissionsQuery &packet)
 
void HandleGuildBankMoneyWithdrawn (WorldPackets::Guild::GuildBankRemainingWithdrawMoneyQuery &packet)
 
void HandleGuildBankerActivate (WorldPackets::Guild::GuildBankActivate &packet)
 
void HandleGuildBankQueryTab (WorldPackets::Guild::GuildBankQueryTab &packet)
 
void HandleGuildBankLogQuery (WorldPackets::Guild::GuildBankLogQuery &packet)
 
void HandleGuildBankDepositMoney (WorldPackets::Guild::GuildBankDepositMoney &packet)
 
void HandleGuildBankWithdrawMoney (WorldPackets::Guild::GuildBankWithdrawMoney &packet)
 
void HandleGuildBankSwapItems (WorldPackets::Guild::GuildBankSwapItems &packet)
 
void HandleGuildBankUpdateTab (WorldPackets::Guild::GuildBankUpdateTab &packet)
 
void HandleGuildBankBuyTab (WorldPackets::Guild::GuildBankBuyTab &packet)
 
void HandleQueryGuildBankTabText (WorldPackets::Guild::GuildBankTextQuery &packet)
 
void HandleSetGuildBankTabText (WorldPackets::Guild::GuildBankSetTabText &packet)
 
void HandleGrantLevel (WorldPacket &recvData)
 
void HandleAcceptGrantLevel (WorldPacket &recvData)
 
void HandleCalendarGetCalendar (WorldPacket &recvData)
 
void HandleCalendarGetEvent (WorldPacket &recvData)
 
void HandleCalendarGuildFilter (WorldPacket &recvData)
 
void HandleCalendarArenaTeam (WorldPacket &recvData)
 
void HandleCalendarAddEvent (WorldPacket &recvData)
 
void HandleCalendarUpdateEvent (WorldPacket &recvData)
 
void HandleCalendarRemoveEvent (WorldPacket &recvData)
 
void HandleCalendarCopyEvent (WorldPacket &recvData)
 
void HandleCalendarEventInvite (WorldPacket &recvData)
 
void HandleCalendarEventRsvp (WorldPacket &recvData)
 
void HandleCalendarEventRemoveInvite (WorldPacket &recvData)
 
void HandleCalendarEventStatus (WorldPacket &recvData)
 
void HandleCalendarEventModeratorStatus (WorldPacket &recvData)
 
void HandleCalendarComplain (WorldPacket &recvData)
 
void HandleCalendarGetNumPending (WorldPacket &recvData)
 
void HandleCalendarEventSignup (WorldPacket &recvData)
 
void SendCalendarRaidLockout (InstanceSave const *save, bool add)
 
void SendCalendarRaidLockoutUpdated (InstanceSave const *save, bool isExtended)
 
void HandleSetSavedInstanceExtend (WorldPacket &recvData)
 
void HandleSpellClick (WorldPacket &recvData)
 
void HandleMirrorImageDataRequest (WorldPacket &recvData)
 
void HandleAlterAppearance (WorldPacket &recvData)
 
void HandleRemoveGlyph (WorldPacket &recvData)
 
void HandleCharCustomize (WorldPacket &recvData)
 
void HandleCharCustomizeCallback (std::shared_ptr< CharacterCustomizeInfo > customizeInfo, PreparedQueryResult result)
 
void HandleQueryInspectAchievements (WorldPacket &recvData)
 
void HandleEquipmentSetSave (WorldPacket &recvData)
 
void HandleEquipmentSetDelete (WorldPacket &recvData)
 
void HandleEquipmentSetUse (WorldPacket &recvData)
 
void HandleWorldStateUITimerUpdate (WorldPacket &recvData)
 
void HandleReadyForAccountDataTimes (WorldPacket &recvData)
 
void HandleQueryQuestsCompleted (WorldPacket &recvData)
 
void HandleQuestPOIQuery (WorldPacket &recvData)
 
void HandleEjectPassenger (WorldPacket &data)
 
void HandleEnterPlayerVehicle (WorldPacket &data)
 
void HandleUpdateProjectilePosition (WorldPacket &recvPacket)
 
void HandleTeleportTimeout (bool updateInSessions)
 
bool HandleSocketClosed ()
 
void SetOfflineTime (uint32 time)
 
uint32 GetOfflineTime () const
 
bool IsKicked () const
 
void SetKicked (bool val)
 
void SetShouldSetOfflineInDB (bool val)
 
bool GetShouldSetOfflineInDB () const
 
bool IsSocketClosed () const
 
QueryCallbackProcessorGetQueryProcessor ()
 
TransactionCallbackAddTransactionCallback (TransactionCallback &&callback)
 
SQLQueryHolderCallbackAddQueryHolderCallback (SQLQueryHolderCallback &&callback)
 

Public Attributes

time_t m_muteTime
 
std::atomic< time_t > m_timeOutTime
 
uint32 _lastAuctionListItemsMSTime
 
uint32 _lastAuctionListOwnerItemsMSTime
 

Protected Attributes

class WorldSession::DosProtection AntiDOS
 

Private Types

typedef std::list< AddonInfoAddonsList
 

Private Member Functions

void ProcessQueryCallbacks ()
 
void moveItems (Item *myItems[], Item *hisItems[])
 
bool CanUseBank (ObjectGuid bankerGUID=ObjectGuid::Empty) const
 
bool recoveryItem (Item *pItem)
 
void LogUnexpectedOpcode (WorldPacket *packet, char const *status, const char *reason)
 Logging helper for unexpected opcodes. More...
 
void LogUnprocessedTail (WorldPacket *packet)
 Logging helper for unexpected opcodes. More...
 
bool IsLegitCharacterForAccount (ObjectGuid guid)
 
void ComputeNewClockDelta ()
 
 WorldSession (WorldSession const &right)=delete
 
WorldSessionoperator= (WorldSession const &right)=delete
 

Private Attributes

QueryCallbackProcessor _queryProcessor
 
AsyncCallbackProcessor< TransactionCallback_transactionCallbacks
 
AsyncCallbackProcessor< SQLQueryHolderCallback_queryHolderProcessor
 
GuidSet _legitCharacters
 
ObjectGuid::LowType m_GUIDLow
 
Player_player
 
std::shared_ptr< WorldSocketm_Socket
 
std::string m_Address
 
AccountTypes _security
 
bool _skipQueue
 
uint32 _accountId
 
std::string _accountName
 
uint8 m_expansion
 
uint32 m_total_time
 
std::unique_ptr< Warden_warden
 
time_t _logoutTime
 
bool m_inQueue
 
bool m_playerLoading
 
bool m_playerLogout
 
bool m_playerSave
 
LocaleConstant m_sessionDbcLocale
 
LocaleConstant m_sessionDbLocaleIndex
 
std::atomic< uint32m_latency
 
AccountData m_accountData [NUM_ACCOUNT_DATA_TYPES]
 
uint32 m_Tutorials [MAX_ACCOUNT_TUTORIAL_VALUES]
 
bool m_TutorialsChanged
 
AddonsList m_addonsList
 
uint32 recruiterId
 
bool isRecruiter
 
LockedQueue< WorldPacket * > _recvQueue
 
uint32 m_currentVendorEntry
 
ObjectGuid m_currentBankerGUID
 
uint32 _offlineTime
 
bool _kicked
 
bool _shouldSetOfflineInDB
 
time_t _calendarEventCreationCooldown
 
std::atomic< uint32_addonMessageReceiveCount
 
CircularBuffer< std::pair< int64, uint32 > > _timeSyncClockDeltaQueue
 
int64 _timeSyncClockDelta
 
std::map< uint32, uint32_pendingTimeSyncRequests
 
uint32 _timeSyncNextCounter
 
uint32 _timeSyncTimer
 

Friends

class World
 

Detailed Description

Player session in the World.

Definition at line 329 of file WorldSession.h.

Member Typedef Documentation

◆ AddonsList

typedef std::list<AddonInfo> WorldSession::AddonsList
private

Definition at line 1151 of file WorldSession.h.

Constructor & Destructor Documentation

◆ WorldSession() [1/2]

WorldSession::WorldSession ( uint32  id,
std::string &&  name,
std::shared_ptr< WorldSocket sock,
AccountTypes  sec,
uint8  expansion,
time_t  mute_time,
LocaleConstant  locale,
uint32  recruiter,
bool  isARecruiter,
bool  skipQueue,
uint32  TotalTime 
)

WorldSession constructor.

Definition at line 104 of file WorldSession.cpp.

105 :
106 m_muteTime(mute_time),
107 m_timeOutTime(0),
110 AntiDOS(this),
111 m_GUIDLow(0),
112 _player(nullptr),
113 m_Socket(sock),
114 _security(sec),
115 _skipQueue(skipQueue),
116 _accountId(id),
117 _accountName(std::move(name)),
118 m_expansion(expansion),
119 m_total_time(TotalTime),
120 _logoutTime(0),
121 m_inQueue(false),
122 m_playerLoading(false),
123 m_playerLogout(false),
124 m_playerSave(false),
125 m_sessionDbcLocale(sWorld->GetDefaultDbcLocale()),
127 m_latency(0),
128 m_TutorialsChanged(false),
129 recruiterId(recruiter),
130 isRecruiter(isARecruiter),
137{
138 memset(m_Tutorials, 0, sizeof(m_Tutorials));
139
140 _offlineTime = 0;
141 _kicked = false;
143
145 _timeSyncTimer = 0;
146
147 if (sock)
148 {
149 m_Address = sock->GetRemoteIpAddress().to_string();
150 ResetTimeOutTime(false);
151 LoginDatabase.Execute("UPDATE account SET online = 1 WHERE id = {};", GetAccountId()); // One-time query
152 }
153}
DatabaseWorkerPool< LoginDatabaseConnection > LoginDatabase
Accessor to the realm/login database.
Definition: DatabaseEnv.cpp:22
#define sWorld
Definition: World.h:458
std::string m_Address
uint32 _offlineTime
LocaleConstant m_sessionDbLocaleIndex
CircularBuffer< std::pair< int64, uint32 > > _timeSyncClockDeltaQueue
bool m_TutorialsChanged
bool _shouldSetOfflineInDB
time_t _logoutTime
uint32 m_currentVendorEntry
int64 _timeSyncClockDelta
std::atomic< uint32 > _addonMessageReceiveCount
bool m_playerLoading
std::shared_ptr< WorldSocket > m_Socket
std::map< uint32, uint32 > _pendingTimeSyncRequests
time_t _calendarEventCreationCooldown
class WorldSession::DosProtection AntiDOS
std::atomic< time_t > m_timeOutTime
Definition: WorldSession.h:502
uint32 _timeSyncTimer
uint32 _lastAuctionListOwnerItemsMSTime
uint32 m_total_time
std::string _accountName
uint32 _timeSyncNextCounter
uint32 recruiterId
uint32 _accountId
ObjectGuid::LowType m_GUIDLow
uint32 GetAccountId() const
Definition: WorldSession.h:359
Player * _player
AccountTypes _security
uint32 _lastAuctionListItemsMSTime
LocaleConstant m_sessionDbcLocale
time_t m_muteTime
Definition: WorldSession.h:492
std::atomic< uint32 > m_latency
void ResetTimeOutTime(bool onlyActive)
Definition: WorldSession.h:510
uint32 m_Tutorials[MAX_ACCOUNT_TUTORIAL_VALUES]

◆ ~WorldSession()

WorldSession::~WorldSession ( )

WorldSession destructor.

  • unload player if not unloaded
  • If have unclosed socket, close it
  • empty incoming packet queue

Definition at line 156 of file WorldSession.cpp.

157{
158 LoginDatabase.Execute("UPDATE account SET totaltime = {} WHERE id = {}", GetTotalTime(), GetAccountId());
159
161 if (_player)
162 LogoutPlayer(true);
163
165 if (m_Socket)
166 {
167 m_Socket->CloseSocket();
168 m_Socket = nullptr;
169 }
170
172 WorldPacket* packet = nullptr;
173 while (_recvQueue.next(packet))
174 delete packet;
175
177 LoginDatabase.Execute("UPDATE account SET online = 0 WHERE id = {};", GetAccountId()); // One-time query
178}
bool next(T &result)
Gets the next result in the queue, if any.
Definition: LockedQueue.h:63
void LogoutPlayer(bool save)
Log the player out
uint32 GetTotalTime() const
Definition: WorldSession.h:374
LockedQueue< WorldPacket * > _recvQueue
bool GetShouldSetOfflineInDB() const

◆ WorldSession() [2/2]

WorldSession::WorldSession ( WorldSession const &  right)
privatedelete

Member Function Documentation

◆ AddQueryHolderCallback()

SQLQueryHolderCallback & WorldSession::AddQueryHolderCallback ( SQLQueryHolderCallback &&  callback)

Definition at line 1285 of file WorldSession.cpp.

1286{
1287 return _queryHolderProcessor.AddCallback(std::move(callback));
1288}
AsyncCallbackProcessor< SQLQueryHolderCallback > _queryHolderProcessor

◆ AddTransactionCallback()

TransactionCallback & WorldSession::AddTransactionCallback ( TransactionCallback &&  callback)

Definition at line 1280 of file WorldSession.cpp.

1281{
1282 return _transactionCallbacks.AddCallback(std::move(callback));
1283}
AsyncCallbackProcessor< TransactionCallback > _transactionCallbacks

◆ BuildPartyMemberStatsChangedPacket()

void WorldSession::BuildPartyMemberStatsChangedPacket ( Player player,
WorldPacket data 
)

Definition at line 791 of file GroupHandler.cpp.

792{
793 uint32 mask = player->GetGroupUpdateFlag();
794
795 if (mask == GROUP_UPDATE_FLAG_NONE)
796 return;
797
798 if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) // if update power type, update current/max power also
800
801 if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE) // same for pets
803
804 uint32 byteCount = 0;
805 for (int i = 1; i < GROUP_UPDATE_FLAGS_COUNT; ++i)
806 if (mask & (1 << i))
807 byteCount += GroupUpdateLength[i];
808
809 data->Initialize(SMSG_PARTY_MEMBER_STATS, 8 + 4 + byteCount);
810 *data << player->GetPackGUID();
811 *data << uint32(mask);
812
813 if (mask & GROUP_UPDATE_FLAG_STATUS)
814 {
815 uint16 playerStatus = MEMBER_STATUS_ONLINE;
816 if (player->IsPvP())
817 playerStatus |= MEMBER_STATUS_PVP;
818
819 if (!player->IsAlive())
820 {
822 playerStatus |= MEMBER_STATUS_GHOST;
823 else
824 playerStatus |= MEMBER_STATUS_DEAD;
825 }
826
827 if (player->IsFFAPvP())
828 playerStatus |= MEMBER_STATUS_PVP_FFA;
829
830 if (player->isAFK())
831 playerStatus |= MEMBER_STATUS_AFK;
832
833 if (player->isDND())
834 playerStatus |= MEMBER_STATUS_DND;
835
836 *data << uint16(playerStatus);
837 }
838
839 if (mask & GROUP_UPDATE_FLAG_CUR_HP)
840 *data << uint32(player->GetHealth());
841
842 if (mask & GROUP_UPDATE_FLAG_MAX_HP)
843 *data << uint32(player->GetMaxHealth());
844
845 Powers powerType = player->getPowerType();
847 *data << uint8(powerType);
848
850 *data << uint16(player->GetPower(powerType));
851
853 *data << uint16(player->GetMaxPower(powerType));
854
855 if (mask & GROUP_UPDATE_FLAG_LEVEL)
856 *data << uint16(player->getLevel());
857
858 if (mask & GROUP_UPDATE_FLAG_ZONE)
859 *data << uint16(player->GetZoneId());
860
862 {
863 *data << uint16(player->GetPositionX());
864 *data << uint16(player->GetPositionY());
865 }
866
867 if (mask & GROUP_UPDATE_FLAG_AURAS)
868 {
869 uint64 auramask = player->GetAuraUpdateMaskForRaid();
870 *data << uint64(auramask);
871 for (uint32 i = 0; i < MAX_AURAS_GROUP_UPDATE; ++i)
872 {
873 if (auramask & (uint64(1) << i))
874 {
875 AuraApplication const* aurApp = player->GetVisibleAura(i);
876 *data << uint32(aurApp ? aurApp->GetBase()->GetId() : 0);
877 *data << uint8(1);
878 }
879 }
880 }
881
882 Pet* pet = player->GetPet();
884 {
885 if (pet)
886 *data << pet->GetGUID();
887 else
888 *data << (uint64) 0;
889 }
890
892 {
893 if (pet)
894 *data << pet->GetName();
895 else
896 *data << uint8(0);
897 }
898
900 {
901 if (pet)
902 *data << uint16(pet->GetDisplayId());
903 else
904 *data << uint16(0);
905 }
906
908 {
909 if (pet)
910 *data << uint32(pet->GetHealth());
911 else
912 *data << uint32(0);
913 }
914
916 {
917 if (pet)
918 *data << uint32(pet->GetMaxHealth());
919 else
920 *data << uint32(0);
921 }
922
924 {
925 if (pet)
926 *data << uint8(pet->getPowerType());
927 else
928 *data << uint8(0);
929 }
930
932 {
933 if (pet)
934 *data << uint16(pet->GetPower(pet->getPowerType()));
935 else
936 *data << uint16(0);
937 }
938
940 {
941 if (pet)
942 *data << uint16(pet->GetMaxPower(pet->getPowerType()));
943 else
944 *data << uint16(0);
945 }
946
948 {
949 if (pet)
950 {
951 uint64 auramask = pet->GetAuraUpdateMaskForRaid();
952 *data << uint64(auramask);
953 for (uint32 i = 0; i < MAX_AURAS_GROUP_UPDATE; ++i)
954 {
955 if (auramask & (uint64(1) << i))
956 {
957 AuraApplication const* aurApp = pet->GetVisibleAura(i);
958 *data << uint32(aurApp ? aurApp->GetBase()->GetId() : 0);
959 *data << uint8(aurApp ? aurApp->GetFlags() : 0);
960 }
961 }
962 }
963 else
964 *data << uint64(0);
965 }
966
968 {
969 if (Vehicle* veh = player->GetVehicle())
970 * data << uint32(veh->GetVehicleInfo()->m_seatID[player->m_movementInfo.transport.seat]);
971 else
972 *data << uint32(0);
973 }
974}
std::uint8_t uint8
Definition: Define.h:110
std::uint32_t uint32
Definition: Define.h:108
std::uint64_t uint64
Definition: Define.h:107
std::uint16_t uint16
Definition: Define.h:109
@ PLAYER_FLAGS_GHOST
Definition: Player.h:479
@ MEMBER_STATUS_AFK
Definition: Group.h:66
@ MEMBER_STATUS_PVP
Definition: Group.h:61
@ MEMBER_STATUS_ONLINE
Definition: Group.h:60
@ MEMBER_STATUS_DEAD
Definition: Group.h:62
@ MEMBER_STATUS_GHOST
Definition: Group.h:63
@ MEMBER_STATUS_DND
Definition: Group.h:67
@ MEMBER_STATUS_PVP_FFA
Definition: Group.h:64
static const uint8 GroupUpdateLength[GROUP_UPDATE_FLAGS_COUNT]
Definition: Group.h:139
@ GROUP_UPDATE_FLAG_CUR_HP
Definition: Group.h:100
@ GROUP_UPDATE_FLAG_PET_CUR_HP
Definition: Group.h:112
@ GROUP_UPDATE_FLAG_POWER_TYPE
Definition: Group.h:102
@ GROUP_UPDATE_FLAG_PET_CUR_POWER
Definition: Group.h:115
@ GROUP_UPDATE_FLAG_PET_MAX_POWER
Definition: Group.h:116
@ GROUP_UPDATE_FLAG_MAX_HP
Definition: Group.h:101
@ GROUP_UPDATE_FLAG_VEHICLE_SEAT
Definition: Group.h:118
@ GROUP_UPDATE_FLAG_STATUS
Definition: Group.h:99
@ GROUP_UPDATE_FLAG_PET_POWER_TYPE
Definition: Group.h:114
@ GROUP_UPDATE_FLAG_MAX_POWER
Definition: Group.h:104
@ GROUP_UPDATE_FLAG_ZONE
Definition: Group.h:106
@ GROUP_UPDATE_FLAG_NONE
Definition: Group.h:98
@ GROUP_UPDATE_FLAG_POSITION
Definition: Group.h:107
@ GROUP_UPDATE_FLAG_PET_MODEL_ID
Definition: Group.h:111
@ GROUP_UPDATE_FLAG_PET_NAME
Definition: Group.h:110
@ GROUP_UPDATE_FLAG_PET_AURAS
Definition: Group.h:117
@ GROUP_UPDATE_FLAG_AURAS
Definition: Group.h:108
@ GROUP_UPDATE_FLAG_LEVEL
Definition: Group.h:105
@ GROUP_UPDATE_FLAG_PET_GUID
Definition: Group.h:109
@ GROUP_UPDATE_FLAG_PET_MAX_HP
Definition: Group.h:113
@ GROUP_UPDATE_FLAG_CUR_POWER
Definition: Group.h:103
#define GROUP_UPDATE_FLAGS_COUNT
Definition: Group.h:137
#define MAX_AURAS_GROUP_UPDATE
Powers
@ SMSG_PARTY_MEMBER_STATS
Definition: Opcodes.h:156
PackedGuid const & GetPackGUID() const
Definition: Object.h:108
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:106
struct MovementInfo::TransportInfo transport
std::string const & GetName() const
Definition: Object.h:446
uint32 GetZoneId() const
Definition: Object.cpp:3058
MovementInfo m_movementInfo
Definition: Object.h:595
float GetPositionX() const
Definition: Position.h:117
float GetPositionY() const
Definition: Position.h:118
Definition: Pet.h:40
uint64 GetAuraUpdateMaskForRaid() const
Definition: Pet.h:134
uint64 GetAuraUpdateMaskForRaid() const
Definition: Player.h:2424
Pet * GetPet() const
Definition: Player.cpp:8764
bool IsFFAPvP()
Definition: Player.cpp:15909
bool isDND() const
Definition: Player.h:1115
uint32 GetGroupUpdateFlag() const
Definition: Player.h:2422
bool HasPlayerFlag(PlayerFlags flags) const
Definition: Player.h:1090
bool isAFK() const
Definition: Player.h:1114
bool IsPvP()
Definition: Player.cpp:15918
Vehicle * GetVehicle() const
Definition: Unit.h:2349
AuraApplication * GetVisibleAura(uint8 slot)
Definition: Unit.h:2149
uint32 GetMaxHealth() const
Definition: Unit.h:1439
bool IsAlive() const
Definition: Unit.h:1805
uint32 GetDisplayId() const
Definition: Unit.h:2163
uint32 GetMaxPower(Powers power) const
Definition: Unit.h:1460
uint32 GetHealth() const
Definition: Unit.h:1438
Powers getPowerType() const
Definition: Unit.h:1457
uint32 GetPower(Powers power) const
Definition: Unit.h:1459
uint8 getLevel() const
Definition: Unit.h:1418
void Initialize(uint16 opcode, size_t newres=200)
Definition: WorldPacket.h:69
uint8 GetFlags() const
Definition: SpellAuras.h:65
Aura * GetBase() const
Definition: SpellAuras.h:62
uint32 GetId() const
Definition: SpellAuras.cpp:466

◆ CanOpenMailBox()

bool WorldSession::CanOpenMailBox ( ObjectGuid  guid)

Definition at line 36 of file MailHandler.cpp.

37{
38 if (guid == _player->GetGUID())
39 {
41 {
42 LOG_ERROR("network.opcode", "{} attempt open mailbox in cheating way.", _player->GetName());
43 return false;
44 }
45 }
46 else if (guid.IsGameObject())
47 {
49 return false;
50 }
51 else if (guid.IsAnyTypeCreature())
52 {
54 return false;
55 }
56 else
57 return false;
58
59 return true;
60}
@ SEC_MODERATOR
Definition: Common.h:67
#define LOG_ERROR(filterType__,...)
Definition: Log.h:159
@ UNIT_NPC_FLAG_MAILBOX
Definition: Unit.h:542
@ GAMEOBJECT_TYPE_MAILBOX
bool IsGameObject() const
Definition: ObjectGuid.h:173
bool IsAnyTypeCreature() const
Definition: ObjectGuid.h:169
GameObject * GetGameObjectIfCanInteractWith(ObjectGuid guid, GameobjectTypes type) const
Definition: Player.cpp:2097
WorldSession * GetSession() const
Definition: Player.h:1947
Creature * GetNPCIfCanInteractWith(ObjectGuid guid, uint32 npcflagmask)
Definition: Player.cpp:2040
AccountTypes GetSecurity() const
Definition: WorldSession.h:357

◆ CanSkipQueue()

bool WorldSession::CanSkipQueue ( ) const
inline

Definition at line 358 of file WorldSession.h.

358{ return _skipQueue; }

◆ CanUseBank()

bool WorldSession::CanUseBank ( ObjectGuid  bankerGUID = ObjectGuid::Empty) const
private

Definition at line 27 of file BankHandler.cpp.

28{
29 // bankerGUID parameter is optional, set to 0 by default.
30 if (!bankerGUID)
31 bankerGUID = m_currentBankerGUID;
32
33 bool isUsingBankCommand = (bankerGUID == GetPlayer()->GetGUID() && bankerGUID == m_currentBankerGUID);
34
35 if (!isUsingBankCommand)
36 {
38 if (!creature)
39 return false;
40 }
41
42 return true;
43}
@ UNIT_NPC_FLAG_BANKER
Definition: Unit.h:533
Player * GetPlayer() const
Definition: WorldSession.h:360
ObjectGuid m_currentBankerGUID

◆ CheckStableMaster()

bool WorldSession::CheckStableMaster ( ObjectGuid  guid)

Definition at line 657 of file PetHandler.cpp.

658{
659 // spell case or GM
660 if (guid == GetPlayer()->GetGUID())
661 {
662 if (!GetPlayer()->IsGameMaster() && !GetPlayer()->HasAuraType(SPELL_AURA_OPEN_STABLE))
663 {
664 LOG_DEBUG("network.opcode", "Player ({}) attempt open stable in cheating way.", guid.ToString());
665 return false;
666 }
667 }
668 // stable master case
669 else
670 {
671 if (!GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_STABLEMASTER))
672 {
673 LOG_DEBUG("network.opcode", "Stablemaster ({}) not found or you can't interact with him.", guid.ToString());
674 return false;
675 }
676 }
677 return true;
678}
#define LOG_DEBUG(filterType__,...)
Definition: Log.h:171
@ UNIT_NPC_FLAG_STABLEMASTER
Definition: Unit.h:538
@ SPELL_AURA_OPEN_STABLE
std::string ToString() const
Definition: ObjectGuid.cpp:47

◆ ComputeNewClockDelta()

void WorldSession::ComputeNewClockDelta ( )
private

Definition at line 915 of file MovementHandler.cpp.

916{
917 // implementation of the technique described here: https://web.archive.org/web/20180430214420/http://www.mine-control.com/zack/timesync/timesync.html
918 // to reduce the skew induced by dropped TCP packets that get resent.
919
920 std::vector<uint32> latencies;
921 std::vector<int64> clockDeltasAfterFiltering;
922
923 for (auto& pair : _timeSyncClockDeltaQueue.content())
924 latencies.push_back(pair.second);
925
926 uint32 latencyMedian = median(latencies);
927 uint32 latencyStandardDeviation = standard_deviation(latencies);
928
929 uint32 sampleSizeAfterFiltering = 0;
930 for (auto& pair : _timeSyncClockDeltaQueue.content())
931 {
932 if (pair.second <= latencyMedian + latencyStandardDeviation) {
933 clockDeltasAfterFiltering.push_back(pair.first);
934 sampleSizeAfterFiltering++;
935 }
936 }
937
938 if (sampleSizeAfterFiltering != 0)
939 {
940 int64 meanClockDelta = static_cast<int64>(mean(clockDeltasAfterFiltering));
941 if (std::abs(meanClockDelta - _timeSyncClockDelta) > 25)
942 _timeSyncClockDelta = meanClockDelta;
943 }
944 else if (_timeSyncClockDelta == 0)
945 {
946 std::pair<int64, uint32> back = _timeSyncClockDeltaQueue.peak_back();
947 _timeSyncClockDelta = back.first;
948 }
949}
std::int64_t int64
Definition: Define.h:103
T median(std::vector< T > a)
Definition: MathUtil.h:59
T standard_deviation(Container &&c)
Definition: MathUtil.h:28
T mean(Container &&c)
Definition: MathUtil.h:49
std::vector< T > content()

◆ DisallowHyperlinksAndMaybeKick()

bool WorldSession::DisallowHyperlinksAndMaybeKick ( std::string_view  str)

Definition at line 749 of file WorldSession.cpp.

750{
751 if (str.find('|') == std::string_view::npos)
752 return true;
753
754 LOG_ERROR("network", "Player {} {} sent a message which illegally contained a hyperlink:\n%.*s", GetPlayer()->GetName(),
755 GetPlayer()->GetGUID().ToString(), STRING_VIEW_FMT_ARG(str));
756
758 KickPlayer("WorldSession::DisallowHyperlinksAndMaybeKick Illegal chat link");
759
760 return false;
761}
#define STRING_VIEW_FMT_ARG(str)
Definition: Define.h:101
@ CONFIG_CHAT_STRICT_LINK_CHECKING_KICK
Definition: IWorld.h:283
std::string ToString(Type &&val, Params &&... params)
bool GetName(uint32 accountId, std::string &name)
Definition: AccountMgr.cpp:228
void KickPlayer(bool setKicked=true)
Definition: WorldSession.h:397

◆ DoLootRelease()

void WorldSession::DoLootRelease ( ObjectGuid  lguid)

Definition at line 258 of file LootHandler.cpp.

259{
260 Player* player = GetPlayer();
261 Loot* loot;
262
264 player->SendLootRelease(lguid);
265
267
268 if (!player->IsInWorld())
269 return;
270
271 if (lguid.IsGameObject())
272 {
273 GameObject* go = GetPlayer()->GetMap()->GetGameObject(lguid);
274
275 // not check distance for GO in case owned GO (fishing bobber case, for example) or Fishing hole GO
276 if (!go || ((go->GetOwnerGUID() != _player->GetGUID() && go->GetGoType() != GAMEOBJECT_TYPE_FISHINGHOLE) && !go->IsWithinDistInMap(_player)))
277 {
278 return;
279 }
280
281 loot = &go->loot;
282
283 if (go->GetGoType() == GAMEOBJECT_TYPE_DOOR)
284 {
285 // locked doors are opened with spelleffect openlock, prevent remove its as looted
286 go->UseDoorOrButton();
287 }
288 else if (loot->isLooted() || go->GetGoType() == GAMEOBJECT_TYPE_FISHINGNODE)
289 {
291 {
292 // The fishing hole used once more
293 go->AddUse(); // if the max usage is reached, will be despawned in next tick
294 if (go->GetUseCount() >= go->GetGOValue()->FishingHole.MaxOpens)
296 else
298 }
299 else
300 {
302
303 // Xinef: moved event execution to loot release (after everything is looted)
304 // Xinef: 99% sure that this worked like this on blizz
305 // Xinef: prevents exploits with just opening GO and spawning bilions of npcs, which can crash core if you know what you're doin ;)
307 {
308 LOG_DEBUG("spells.aura", "Chest ScriptStart id {} for GO {}", go->GetGOInfo()->chest.eventId, go->GetSpawnId());
309 player->GetMap()->ScriptsStart(sEventScripts, go->GetGOInfo()->chest.eventId, player, go);
310 }
311 }
312
313 loot->clear();
314 }
315 else
316 {
317 // not fully looted object
318 go->SetLootState(GO_ACTIVATED, player);
319
320 // if the round robin player release, reset it.
321 if (player->GetGUID() == loot->roundRobinPlayer)
322 loot->roundRobinPlayer.Clear();
323 }
324 }
325 else if (lguid.IsCorpse()) // ONLY remove insignia at BG
326 {
327 Corpse* corpse = ObjectAccessor::GetCorpse(*player, lguid);
328 if (!corpse || !corpse->IsWithinDistInMap(_player, INTERACTION_DISTANCE))
329 return;
330
331 loot = &corpse->loot;
332
333 // Xinef: Buggs client? (Opening loot after closing)
334 //if (loot->isLooted())
335 {
336 loot->clear();
338 }
339 }
340 else if (lguid.IsItem())
341 {
342 Item* pItem = player->GetItemByGuid(lguid);
343 if (!pItem)
344 return;
345
346 loot = &pItem->loot;
347 ItemTemplate const* proto = pItem->GetTemplate();
348
349 // destroy only 5 items from stack in case prospecting and milling
351 {
352 pItem->m_lootGenerated = false;
353 pItem->loot.clear();
354
355 uint32 count = pItem->GetCount();
356
357 // >=5 checked in spell code, but will work for cheating cases also with removing from another stacks.
358 if (count > 5)
359 count = 5;
360
361 player->DestroyItemCount(pItem, count, true);
362 }
363 else if (pItem->loot.isLooted() || !(proto->Flags & ITEM_FLAG_HAS_LOOT))
364 {
365 player->DestroyItem(pItem->GetBagSlot(), pItem->GetSlot(), true);
366 return;
367 }
368 }
369 else
370 {
371 Creature* creature = GetPlayer()->GetMap()->GetCreature(lguid);
372
373 bool lootAllowed = creature && creature->IsAlive() == (player->getClass() == CLASS_ROGUE && creature->loot.loot_type == LOOT_PICKPOCKETING);
374 if (!lootAllowed || !creature->IsWithinDistInMap(_player, INTERACTION_DISTANCE))
375 return;
376
377 loot = &creature->loot;
378 if (loot->isLooted())
379 {
380 // skip pickpocketing loot for speed, skinning timer reduction is no-op in fact
381 if (!creature->IsAlive())
382 creature->AllLootRemovedFromCorpse();
383
385 loot->clear();
386 }
387 else
388 {
389 // if the round robin player release, reset it.
390 if (player->GetGUID() == loot->roundRobinPlayer)
391 {
392 loot->roundRobinPlayer.Clear();
393
394 if (Group* group = player->GetGroup())
395 group->SendLooter(creature, nullptr);
396 }
397 // force dynflag update to update looter and lootable info
399 }
400 }
401
402 //Player is not looking at loot list, he doesn't need to see updates on the loot list
403 loot->RemoveLooter(player->GetGUID());
404}
@ GO_ACTIVATED
Definition: GameObject.h:802
@ GO_READY
Definition: GameObject.h:801
@ GO_JUST_DEACTIVATED
Definition: GameObject.h:803
@ ITEM_FLAG_IS_MILLABLE
Definition: ItemTemplate.h:177
@ ITEM_FLAG_IS_PROSPECTABLE
Definition: ItemTemplate.h:166
@ ITEM_FLAG_HAS_LOOT
Definition: ItemTemplate.h:150
#define INTERACTION_DISTANCE
Definition: ObjectDefines.h:24
@ CORPSE_FIELD_DYNAMIC_FLAGS
Definition: UpdateFields.h:428
@ UNIT_DYNAMIC_FLAGS
Definition: UpdateFields.h:136
@ UNIT_FLAG_LOOTING
Definition: Unit.h:458
ScriptMapMap sEventScripts
Definition: ObjectMgr.cpp:58
@ LOOT_PICKPOCKETING
Definition: LootMgr.h:82
@ GAMEOBJECT_TYPE_CHEST
@ GAMEOBJECT_TYPE_FISHINGHOLE
@ GAMEOBJECT_TYPE_FISHINGNODE
@ GAMEOBJECT_TYPE_DOOR
@ CORPSE_DYNFLAG_LOOTABLE
@ UNIT_DYNFLAG_LOOTABLE
@ CLASS_ROGUE
Corpse * GetCorpse(WorldObject const &u, ObjectGuid const guid)
Definition: Corpse.h:49
Loot loot
Definition: Corpse.h:77
Loot loot
Definition: Creature.h:217
void AllLootRemovedFromCorpse()
Definition: Creature.cpp:2864
struct GameObjectTemplate::@209::@214 chest
struct GameObjectValue::@241 FishingHole
bool IsWithinDistInMap(Player const *player) const
void UseDoorOrButton(uint32 time_to_restore=0, bool alternative=false, Unit *user=nullptr)
GameObjectTemplate const * GetGOInfo() const
Definition: GameObject.h:829
void AddUse()
Definition: GameObject.h:932
GameObjectValue const * GetGOValue() const
Definition: GameObject.h:832
void SetLootState(LootState s, Unit *unit=nullptr)
ObjectGuid GetOwnerGUID() const
Definition: GameObject.h:866
GameobjectTypes GetGoType() const
Definition: GameObject.h:896
ObjectGuid::LowType GetSpawnId() const
Definition: GameObject.h:837
uint32 GetUseCount() const
Definition: GameObject.h:934
Definition: Item.h:214
uint8 GetSlot() const
Definition: Item.h:272
ItemTemplate const * GetTemplate() const
Definition: Item.cpp:546
bool m_lootGenerated
Definition: Item.h:312
uint32 GetCount() const
Definition: Item.h:263
Loot loot
Definition: Item.h:311
uint8 GetBagSlot() const
Definition: Item.cpp:786
virtual void RemoveDynamicFlag(uint32 flag)
Definition: Object.h:118
bool IsInWorld() const
Definition: Object.h:101
void RemoveFlag(uint16 index, uint32 oldFlag)
Definition: Object.cpp:860
void ForceValuesUpdateAtIndex(uint32)
Definition: Object.cpp:2028
Map * GetMap() const
Definition: Object.h:517
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool useBoundingRadius=true) const
Definition: Object.cpp:1321
static ObjectGuid const Empty
Definition: ObjectGuid.h:122
bool IsCorpse() const
Definition: ObjectGuid.h:175
bool IsItem() const
Definition: ObjectGuid.h:172
void Clear()
Definition: ObjectGuid.h:140
void SendLootRelease(ObjectGuid guid)
Definition: Player.cpp:7630
void SetLootGUID(ObjectGuid guid)
Definition: Player.h:1943
void DestroyItem(uint8 bag, uint8 slot, bool update)
Group * GetGroup()
Definition: Player.h:2417
void DestroyItemCount(uint32 item, uint32 count, bool update, bool unequip_check=false)
Item * GetItemByGuid(ObjectGuid guid) const
uint8 getClass() const
Definition: Unit.h:1424
void RemoveUnitFlag(UnitFlags flags)
Definition: Unit.h:1480
Definition: Group.h:168
Definition: LootMgr.h:313
bool isLooted() const
Definition: LootMgr.h:368
void clear()
Definition: LootMgr.h:343
ObjectGuid roundRobinPlayer
Definition: LootMgr.h:324
void RemoveLooter(ObjectGuid GUID)
Definition: LootMgr.h:374
LootType loot_type
Definition: LootMgr.h:326
void ScriptsStart(std::map< uint32, std::multimap< uint32, ScriptInfo > > const &scripts, uint32 id, Object *source, Object *target)
Put scripts in the execution queue.
Definition: MapScripts.cpp:34
GameObject * GetGameObject(ObjectGuid const guid)
Definition: Map.cpp:3295
Creature * GetCreature(ObjectGuid const guid)
Definition: Map.cpp:3290

◆ Expansion()

uint8 WorldSession::Expansion ( ) const
inline

Definition at line 371 of file WorldSession.h.

371{ return m_expansion; }

◆ GetAccountData()

AccountData * WorldSession::GetAccountData ( AccountDataType  type)
inline

Definition at line 447 of file WorldSession.h.

447{ return &m_accountData[type]; }
AccountData m_accountData[NUM_ACCOUNT_DATA_TYPES]

◆ GetAccountId()

uint32 WorldSession::GetAccountId ( ) const
inline

Definition at line 359 of file WorldSession.h.

359{ return _accountId; }

◆ GetAcoreString()

char const * WorldSession::GetAcoreString ( uint32  entry) const

Definition at line 798 of file WorldSession.cpp.

799{
800 return sObjectMgr->GetAcoreString(entry, GetSessionDbLocaleIndex());
801}
#define sObjectMgr
Definition: ObjectMgr.h:1606
LocaleConstant GetSessionDbLocaleIndex() const
Definition: WorldSession.h:496

◆ GetCalendarEventCreationCooldown()

time_t WorldSession::GetCalendarEventCreationCooldown ( ) const
inline

Definition at line 527 of file WorldSession.h.

◆ GetCurrentVendor()

uint32 WorldSession::GetCurrentVendor ( ) const
inline

Definition at line 364 of file WorldSession.h.

364{ return m_currentVendorEntry; }

◆ GetGuidLow()

ObjectGuid::LowType WorldSession::GetGuidLow ( ) const

Get player guid if available. Use for logging purposes only.

Definition at line 202 of file WorldSession.cpp.

203{
204 return GetPlayer() ? GetPlayer()->GetGUID().GetCounter() : 0;
205}
LowType GetCounter() const
Definition: ObjectGuid.h:147

◆ GetLatency()

uint32 WorldSession::GetLatency ( ) const
inline

Definition at line 499 of file WorldSession.h.

499{ return m_latency; }

◆ GetOfflineTime()

uint32 WorldSession::GetOfflineTime ( ) const
inline

Definition at line 1065 of file WorldSession.h.

1065{ return _offlineTime; }

◆ GetPlayer()

Player * WorldSession::GetPlayer ( ) const
inline

Definition at line 360 of file WorldSession.h.

360{ return _player; }

◆ GetPlayerInfo()

std::string WorldSession::GetPlayerInfo ( ) const

Definition at line 185 of file WorldSession.cpp.

186{
187 std::ostringstream ss;
188
189 ss << "[Player: ";
190
191 if (!m_playerLoading && _player)
192 {
193 ss << _player->GetName() << ' ' << _player->GetGUID().ToString() << ", ";
194 }
195
196 ss << "Account: " << GetAccountId() << "]";
197
198 return ss.str();
199}

◆ GetPlayerName()

std::string const & WorldSession::GetPlayerName ( ) const

Definition at line 180 of file WorldSession.cpp.

181{
183}

◆ GetQueryProcessor()

QueryCallbackProcessor & WorldSession::GetQueryProcessor ( )
inline

Definition at line 1076 of file WorldSession.h.

1076{ return _queryProcessor; }
QueryCallbackProcessor _queryProcessor

◆ GetRecruiterId()

uint32 WorldSession::GetRecruiterId ( ) const
inline

Definition at line 523 of file WorldSession.h.

523{ return recruiterId; }

◆ GetRemoteAddress()

std::string const & WorldSession::GetRemoteAddress ( )
inline

Definition at line 369 of file WorldSession.h.

369{ return m_Address; }

◆ GetSecurity()

AccountTypes WorldSession::GetSecurity ( ) const
inline

Definition at line 357 of file WorldSession.h.

357{ return _security; }

◆ GetSessionDbcLocale()

LocaleConstant WorldSession::GetSessionDbcLocale ( ) const
inline

Definition at line 495 of file WorldSession.h.

495{ return m_sessionDbcLocale; }

◆ GetSessionDbLocaleIndex()

LocaleConstant WorldSession::GetSessionDbLocaleIndex ( ) const
inline

Definition at line 496 of file WorldSession.h.

496{ return m_sessionDbLocaleIndex; }

◆ GetShouldSetOfflineInDB()

bool WorldSession::GetShouldSetOfflineInDB ( ) const
inline

Definition at line 1069 of file WorldSession.h.

1069{ return _shouldSetOfflineInDB; }

◆ GetTotalTime()

uint32 WorldSession::GetTotalTime ( ) const
inline

Definition at line 374 of file WorldSession.h.

374{ return m_total_time; }

◆ GetTutorialInt()

uint32 WorldSession::GetTutorialInt ( uint8  index) const
inline

Definition at line 456 of file WorldSession.h.

456{ return m_Tutorials[index]; }

◆ Handle_Deprecated()

void WorldSession::Handle_Deprecated ( WorldPacket recvPacket)

Definition at line 821 of file WorldSession.cpp.

822{
823 LOG_ERROR("network.opcode", "Received deprecated opcode {} from {}",
824 GetOpcodeNameForLogging(static_cast<OpcodeClient>(recvPacket.GetOpcode())), GetPlayerInfo());
825}
Opcodes
List of Opcodes.
Definition: Opcodes.h:30
std::string GetOpcodeNameForLogging(Opcodes opcode)
Lookup opcode name for human understandable logging.
Definition: Opcodes.cpp:1468
uint16 GetOpcode() const
Definition: WorldPacket.h:76
std::string GetPlayerInfo() const

◆ Handle_EarlyProccess()

void WorldSession::Handle_EarlyProccess ( WorldPacket recvPacket)

Definition at line 809 of file WorldSession.cpp.

810{
811 LOG_ERROR("network.opcode", "Received opcode {} that must be processed in WorldSocket::ReadDataHandler from {}",
812 GetOpcodeNameForLogging(static_cast<OpcodeClient>(recvPacket.GetOpcode())), GetPlayerInfo());
813}

◆ Handle_NULL()

void WorldSession::Handle_NULL ( WorldPacket null)

Definition at line 803 of file WorldSession.cpp.

804{
805 LOG_ERROR("network.opcode", "Received unhandled opcode {} from {}",
807}

◆ Handle_ServerSide()

void WorldSession::Handle_ServerSide ( WorldPacket recvPacket)

Definition at line 815 of file WorldSession.cpp.

816{
817 LOG_ERROR("network.opcode", "Received server-side opcode {} from {}",
818 GetOpcodeNameForLogging(static_cast<OpcodeServer>(recvPacket.GetOpcode())), GetPlayerInfo());
819}

◆ HandleAcceptGrantLevel()

void WorldSession::HandleAcceptGrantLevel ( WorldPacket recvData)

Definition at line 66 of file ReferAFriendHandler.cpp.

67{
68 LOG_DEBUG("network", "WORLD: CMSG_ACCEPT_LEVEL_GRANT");
69
70 ObjectGuid guid;
71 recvData >> guid.ReadAsPacked();
72
74 if (!other)
75 return;
76
77 if (GetAccountId() != other->GetSession()->GetRecruiterId())
78 return;
79
80 if (other->GetGrantableLevels())
81 other->SetGrantableLevels(other->GetGrantableLevels() - 1);
82 else
83 return;
84
86}
Player * GetPlayer(Map const *, ObjectGuid const guid)
PackedGuidReader ReadAsPacked()
Definition: ObjectGuid.h:137
void GiveLevel(uint8 level)
Definition: Player.cpp:2412
void SetGrantableLevels(uint8 val)
Definition: Player.h:2073
uint8 GetGrantableLevels()
Definition: Player.h:2072
uint32 GetRecruiterId() const
Definition: WorldSession.h:523

◆ HandleAcceptTradeOpcode()

void WorldSession::HandleAcceptTradeOpcode ( WorldPacket recvPacket)

Definition at line 245 of file TradeHandler.cpp.

246{
247 TradeData* my_trade = _player->m_trade;
248 if (!my_trade)
249 return;
250
251 Player* trader = my_trade->GetTrader();
252
253 TradeData* his_trade = trader->m_trade;
254 if (!his_trade)
255 return;
256
257 Item* myItems[TRADE_SLOT_TRADED_COUNT] = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr };
258 Item* hisItems[TRADE_SLOT_TRADED_COUNT] = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr };
259 bool myCanCompleteTrade = true, hisCanCompleteTrade = true;
260
261 // set before checks for propertly undo at problems (it already set in to client)
262 my_trade->SetAccepted(true);
263
264 // not accept case incorrect money amount
265 if (!_player->HasEnoughMoney(my_trade->GetMoney()))
266 {
268 my_trade->SetAccepted(false, true);
269 return;
270 }
271
272 // not accept case incorrect money amount
273 if (!trader->HasEnoughMoney(his_trade->GetMoney()))
274 {
276 his_trade->SetAccepted(false, true);
277 return;
278 }
279
280 if (_player->GetMoney() >= uint32(MAX_MONEY_AMOUNT) - his_trade->GetMoney())
281 {
283 my_trade->SetAccepted(false, true);
284 return;
285 }
286
287 if (trader->GetMoney() >= uint32(MAX_MONEY_AMOUNT) - my_trade->GetMoney())
288 {
289 trader->SendEquipError(EQUIP_ERR_TOO_MUCH_GOLD, nullptr, nullptr);
290 his_trade->SetAccepted(false, true);
291 return;
292 }
293
294 // not accept if some items now can't be trade (cheating)
295 for (uint8 i = 0; i < TRADE_SLOT_TRADED_COUNT; ++i)
296 {
297 if (Item* item = my_trade->GetItem(TradeSlots(i)))
298 {
299 if (!item->CanBeTraded(false, true))
300 {
302 return;
303 }
304
305 if (item->IsBindedNotWith(trader))
306 {
308 SendTradeStatus(TRADE_STATUS_CLOSE_WINDOW/*TRADE_STATUS_TRADE_CANCELED*/);
309 return;
310 }
311 }
312
313 if (Item* item = his_trade->GetItem(TradeSlots(i)))
314 {
315 if (!item->CanBeTraded(false, true))
316 {
318 return;
319 }
320 //if (item->IsBindedNotWith(_player)) // dont mark as invalid when his item isnt good (not exploitable because if item is invalid trade will fail anyway later on the same check)
321 //{
322 // SendTradeStatus(TRADE_STATUS_NOT_ELIGIBLE);
323 // his_trade->SetAccepted(false, true);
324 // return;
325 //}
326 }
327 }
328
329 if (his_trade->IsAccepted())
330 {
331 setAcceptTradeMode(my_trade, his_trade, myItems, hisItems);
332
333 Spell* my_spell = nullptr;
334 SpellCastTargets my_targets;
335
336 Spell* his_spell = nullptr;
337 SpellCastTargets his_targets;
338
339 // not accept if spell can't be casted now (cheating)
340 if (uint32 my_spell_id = my_trade->GetSpell())
341 {
342 SpellInfo const* spellEntry = sSpellMgr->GetSpellInfo(my_spell_id);
343 Item* castItem = my_trade->GetSpellCastItem();
344
345 if (!spellEntry || !his_trade->GetItem(TRADE_SLOT_NONTRADED) ||
346 (my_trade->HasSpellCastItem() && !castItem))
347 {
348 clearAcceptTradeMode(my_trade, his_trade);
349 clearAcceptTradeMode(myItems, hisItems);
350
351 my_trade->SetSpell(0);
352 return;
353 }
354
355 my_spell = new Spell(_player, spellEntry, TRIGGERED_FULL_MASK);
356 my_spell->m_CastItem = castItem;
357 my_targets.SetTradeItemTarget(_player);
358 my_spell->m_targets = my_targets;
359
360 SpellCastResult res = my_spell->CheckCast(true);
361 if (res != SPELL_CAST_OK)
362 {
363 my_spell->SendCastResult(res);
364
365 clearAcceptTradeMode(my_trade, his_trade);
366 clearAcceptTradeMode(myItems, hisItems);
367
368 delete my_spell;
369 my_trade->SetSpell(0);
370 return;
371 }
372 }
373
374 // not accept if spell can't be casted now (cheating)
375 if (uint32 his_spell_id = his_trade->GetSpell())
376 {
377 SpellInfo const* spellEntry = sSpellMgr->GetSpellInfo(his_spell_id);
378 Item* castItem = his_trade->GetSpellCastItem();
379
380 if (!spellEntry || !my_trade->GetItem(TRADE_SLOT_NONTRADED) || (his_trade->HasSpellCastItem() && !castItem))
381 {
382 delete my_spell;
383 his_trade->SetSpell(0);
384
385 clearAcceptTradeMode(my_trade, his_trade);
386 clearAcceptTradeMode(myItems, hisItems);
387 return;
388 }
389
390 his_spell = new Spell(trader, spellEntry, TRIGGERED_FULL_MASK);
391 his_spell->m_CastItem = castItem;
392 his_targets.SetTradeItemTarget(trader);
393 his_spell->m_targets = his_targets;
394
395 SpellCastResult res = his_spell->CheckCast(true);
396 if (res != SPELL_CAST_OK)
397 {
398 his_spell->SendCastResult(res);
399
400 clearAcceptTradeMode(my_trade, his_trade);
401 clearAcceptTradeMode(myItems, hisItems);
402
403 delete my_spell;
404 delete his_spell;
405
406 his_trade->SetSpell(0);
407 return;
408 }
409 }
410
411 // inform partner client
413
414 // test if item will fit in each inventory
415 hisCanCompleteTrade = (trader->CanStoreItems(myItems, TRADE_SLOT_TRADED_COUNT) == EQUIP_ERR_OK);
416 myCanCompleteTrade = (_player->CanStoreItems(hisItems, TRADE_SLOT_TRADED_COUNT) == EQUIP_ERR_OK);
417
418 clearAcceptTradeMode(myItems, hisItems);
419
420 // in case of missing space report error
421 if (!myCanCompleteTrade)
422 {
423 clearAcceptTradeMode(my_trade, his_trade);
424
427 my_trade->SetAccepted(false);
428 his_trade->SetAccepted(false);
429 delete my_spell;
430 delete his_spell;
431 return;
432 }
433 else if (!hisCanCompleteTrade)
434 {
435 clearAcceptTradeMode(my_trade, his_trade);
436
439 my_trade->SetAccepted(false);
440 his_trade->SetAccepted(false);
441 delete my_spell;
442 delete his_spell;
443 return;
444 }
445
446 // execute trade: 1. remove
447 for (uint8 i = 0; i < TRADE_SLOT_TRADED_COUNT; ++i)
448 {
449 if (myItems[i])
450 {
452 _player->MoveItemFromInventory(myItems[i]->GetBagSlot(), myItems[i]->GetSlot(), true);
453 }
454 if (hisItems[i])
455 {
456 hisItems[i]->SetGuidValue(ITEM_FIELD_GIFTCREATOR, trader->GetGUID());
457 trader->MoveItemFromInventory(hisItems[i]->GetBagSlot(), hisItems[i]->GetSlot(), true);
458 }
459 }
460
461 // execute trade: 2. store
462 moveItems(myItems, hisItems);
463
464 if( my_trade->GetMoney() >= 10 * GOLD )
465 {
466 CharacterDatabase.Execute("INSERT INTO log_money VALUES({}, {}, \"{}\", \"{}\", {}, \"{}\", {}, \"goods\", NOW(), {})",
467 GetAccountId(), _player->GetGUID().GetCounter(), _player->GetName(), GetRemoteAddress(), trader->GetSession()->GetAccountId(), trader->GetName(), my_trade->GetMoney(), 6);
468 }
469 if( his_trade->GetMoney() >= 10 * GOLD )
470 {
471 CharacterDatabase.Execute("INSERT INTO log_money VALUES({}, {}, \"{}\", \"{}\", {}, \"{}\", {}, \"goods\", NOW(), {})",
472 trader->GetSession()->GetAccountId(), trader->GetGUID().GetCounter(), trader->GetName(), trader->GetSession()->GetRemoteAddress(), GetAccountId(), _player->GetName(), his_trade->GetMoney(), 6);
473 }
474
475 // update money
476 _player->ModifyMoney(-int32(my_trade->GetMoney()));
477 _player->ModifyMoney(his_trade->GetMoney());
478 trader->ModifyMoney(-int32(his_trade->GetMoney()));
479 trader->ModifyMoney(my_trade->GetMoney());
480
481 if (my_spell)
482 my_spell->prepare(&my_targets);
483
484 if (his_spell)
485 his_spell->prepare(&his_targets);
486
487 // cleanup
488 clearAcceptTradeMode(my_trade, his_trade);
489 delete _player->m_trade;
490 _player->m_trade = nullptr;
491 delete trader->m_trade;
492 trader->m_trade = nullptr;
493
494 // desynchronized with the other saves here (SaveInventoryAndGoldToDB() not have own transaction guards)
495 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
497 trader->SaveInventoryAndGoldToDB(trans);
498 CharacterDatabase.CommitTransaction(trans);
499
502 }
503 else
504 {
506 }
507}
std::int32_t int32
Definition: Define.h:104
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
Definition: DatabaseEnv.cpp:21
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
@ EQUIP_ERR_TOO_MUCH_GOLD
Definition: Item.h:117
@ EQUIP_ERR_OK
Definition: Item.h:41
@ ITEM_FIELD_GIFTCREATOR
Definition: UpdateFields.h:38
#define MAX_MONEY_AMOUNT
Definition: Player.h:922
TradeSlots
Definition: TradeData.h:28
@ TRADE_SLOT_TRADED_COUNT
Definition: TradeData.h:30
@ TRADE_SLOT_NONTRADED
Definition: TradeData.h:31
static void setAcceptTradeMode(TradeData *myTrade, TradeData *hisTrade, Item **myItems, Item **hisItems)
static void clearAcceptTradeMode(TradeData *myTrade, TradeData *hisTrade)
@ LANG_NOT_PARTNER_FREE_TRADE_SLOTS
Definition: Language.h:714
@ LANG_NOT_FREE_TRADE_SLOTS
Definition: Language.h:713
@ LANG_NOT_ENOUGH_GOLD
Definition: Language.h:712
@ TRIGGERED_FULL_MASK
Will return SPELL_FAILED_DONT_REPORT in CheckCast functions.
Definition: SpellDefines.h:148
#define sSpellMgr
Definition: SpellMgr.h:803
@ TRADE_STATUS_TRADE_COMPLETE
@ TRADE_STATUS_TRADE_ACCEPT
@ TRADE_STATUS_TRADE_CANCELED
@ TRADE_STATUS_NOT_ELIGIBLE
@ TRADE_STATUS_CLOSE_WINDOW
@ GOLD
SpellCastResult
@ SPELL_CAST_OK
void SetGuidValue(uint16 index, ObjectGuid value)
Definition: Object.cpp:723
void SaveInventoryAndGoldToDB(CharacterDatabaseTransaction trans)
bool ModifyMoney(int32 amount, bool sendError=true)
Definition: Player.cpp:11225
TradeData * m_trade
Definition: Player.h:2783
bool HasEnoughMoney(uint32 amount) const
Definition: Player.h:1569
void MoveItemFromInventory(uint8 bag, uint8 slot, bool update)
uint32 GetMoney() const
Definition: Player.h:1567
void SendEquipError(InventoryResult msg, Item *pItem, Item *pItem2=nullptr, uint32 itemid=0)
InventoryResult CanStoreItems(Item **pItem, int32 count) const
Item * GetSpellCastItem() const
Definition: TradeData.cpp:49
bool HasSpellCastItem() const
Definition: TradeData.h:53
void SetSpell(uint32 spell_id, Item *castItem=nullptr)
Definition: TradeData.cpp:76
Player * GetTrader() const
Definition: TradeData.h:41
uint32 GetMoney() const
Definition: TradeData.h:55
Item * GetItem(TradeSlots slot) const
Definition: TradeData.cpp:26
bool IsAccepted() const
Definition: TradeData.h:58
uint32 GetSpell() const
Definition: TradeData.h:49
void SetAccepted(bool state, bool crosssend=false)
Definition: TradeData.cpp:120
void moveItems(Item *myItems[], Item *hisItems[])
void SendNotification(const char *format,...) ATTR_PRINTF(2
std::string const & GetRemoteAddress()
Definition: WorldSession.h:369
void SendTradeStatus(TradeStatus status)
void SetTradeItemTarget(Player *caster)
Definition: Spell.cpp:333
Definition: Spell.h:284
SpellCastTargets m_targets
Definition: Spell.h:527
SpellCastResult prepare(SpellCastTargets const *targets, AuraEffect const *triggeredByAura=nullptr)
Definition: Spell.cpp:3438
SpellCastResult CheckCast(bool strict)
Definition: Spell.cpp:5600
static void SendCastResult(Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE)
Definition: Spell.cpp:4619
Item * m_CastItem
Definition: Spell.h:521

◆ HandleActivateTaxiExpressOpcode()

void WorldSession::HandleActivateTaxiExpressOpcode ( WorldPacket recvPacket)

Definition at line 169 of file TaxiHandler.cpp.

170{
171 LOG_DEBUG("network", "WORLD: Received CMSG_ACTIVATETAXIEXPRESS");
172
173 ObjectGuid guid;
174 uint32 node_count;
175
176 recvData >> guid >> node_count;
177
179 if (!npc)
180 {
181 LOG_DEBUG("network", "WORLD: HandleActivateTaxiExpressOpcode - Unit ({}) not found or you can't interact with it.", guid.ToString());
183 return;
184 }
185 std::vector<uint32> nodes;
186
187 for (uint32 i = 0; i < node_count; ++i)
188 {
189 uint32 node;
190 recvData >> node;
191
192 if (!GetPlayer()->m_taxi.IsTaximaskNodeKnown(node) && !GetPlayer()->isTaxiCheater())
193 {
195 recvData.rfinish();
196 return;
197 }
198
199 nodes.push_back(node);
200 }
201
202 if (nodes.empty())
203 return;
204
205 LOG_DEBUG("network", "WORLD: Received CMSG_ACTIVATETAXIEXPRESS from {} to {}", nodes.front(), nodes.back());
206
207 GetPlayer()->ActivateTaxiPathTo(nodes, npc, 0);
208}
npc
@ UNIT_NPC_FLAG_FLIGHTMASTER
Definition: Unit.h:529
@ ERR_TAXINOTVISITED
@ ERR_TAXITOOFARAWAY
bool ActivateTaxiPathTo(std::vector< uint32 > const &nodes, Creature *npc=nullptr, uint32 spellid=1)
Definition: Player.cpp:9960
void SendActivateTaxiReply(ActivateTaxiReply reply)

◆ HandleActivateTaxiOpcode()

void WorldSession::HandleActivateTaxiOpcode ( WorldPacket recvPacket)

Definition at line 264 of file TaxiHandler.cpp.

265{
266 LOG_DEBUG("network", "WORLD: Received CMSG_ACTIVATETAXI");
267
268 ObjectGuid guid;
269 std::vector<uint32> nodes;
270 nodes.resize(2);
271 GetPlayer()->SetCanTeleport(true);
272 recvData >> guid >> nodes[0] >> nodes[1];
273 LOG_DEBUG("network", "WORLD: Received CMSG_ACTIVATETAXI from {} to {}", nodes[0], nodes[1]);
275 if (!npc)
276 {
277 LOG_DEBUG("network", "WORLD: HandleActivateTaxiOpcode - Unit ({}) not found or you can't interact with it.", guid.ToString());
279 return;
280 }
281
282 if (!GetPlayer()->isTaxiCheater())
283 {
284 if (!GetPlayer()->m_taxi.IsTaximaskNodeKnown(nodes[0]) || !GetPlayer()->m_taxi.IsTaximaskNodeKnown(nodes[1]))
285 {
287 return;
288 }
289 }
290
291 GetPlayer()->ActivateTaxiPathTo(nodes, npc, 0);
292}
void SetCanTeleport(bool value)
Definition: Player.h:2447

◆ HandleAddFriendOpcode()

void WorldSession::HandleAddFriendOpcode ( WorldPacket recvPacket)

Definition at line 39 of file Socialhandler.cpp.

40{
41 LOG_DEBUG("network", "WORLD: Received CMSG_ADD_FRIEND");
42
43 std::string friendName = GetAcoreString(LANG_FRIEND_IGNORE_UNKNOWN);
44 std::string friendNote;
45
46 recv_data >> friendName;
47 recv_data >> friendNote;
48
49 if (!normalizePlayerName(friendName))
50 return;
51
52 LOG_DEBUG("network", "WORLD: {} asked to add friend : '{}'", GetPlayer()->GetName(), friendName);
53
54 ObjectGuid friendGuid = sCharacterCache->GetCharacterGuidByName(friendName);
55 if (!friendGuid)
56 return;
57
58 CharacterCacheEntry const* playerData = sCharacterCache->GetCharacterCacheByGuid(friendGuid);
59 if (!playerData)
60 return;
61
62 uint32 friendAccountId = playerData->AccountId;
63 TeamId teamId = Player::TeamIdForRace(playerData->Race);
64 FriendsResult friendResult = FRIEND_NOT_FOUND;
65
67 {
68 if (friendGuid)
69 {
70 if (friendGuid == GetPlayer()->GetGUID())
71 friendResult = FRIEND_SELF;
73 friendResult = FRIEND_ENEMY;
74 else if (GetPlayer()->GetSocial()->HasFriend(friendGuid))
75 friendResult = FRIEND_ALREADY;
76 else
77 {
78 Player* pFriend = ObjectAccessor::FindConnectedPlayer(friendGuid);
79 if (pFriend && pFriend->IsVisibleGloballyFor(GetPlayer()) && !AccountMgr::IsGMAccount(pFriend->GetSession()->GetSecurity()))
80 friendResult = FRIEND_ADDED_ONLINE;
81 else
82 friendResult = FRIEND_ADDED_OFFLINE;
83 if (GetPlayer()->GetSocial()->AddToSocialList(friendGuid, SOCIAL_FLAG_FRIEND))
84 GetPlayer()->GetSocial()->SetFriendNote(friendGuid, friendNote);
85 else
86 friendResult = FRIEND_LIST_FULL;
87 }
88 GetPlayer()->GetSocial()->SetFriendNote(friendGuid, friendNote);
89 }
90 }
91
92 sSocialMgr->SendFriendStatus(GetPlayer(), friendResult, friendGuid, false);
93
94 LOG_DEBUG("network", "WORLD: Sent (SMSG_FRIEND_STATUS)");
95}
#define sCharacterCache
FriendsResult
Results of friend related commands.
Definition: SocialMgr.h:66
@ FRIEND_ENEMY
Definition: SocialMgr.h:77
@ FRIEND_ALREADY
Definition: SocialMgr.h:75
@ FRIEND_ADDED_OFFLINE
Definition: SocialMgr.h:74
@ FRIEND_NOT_FOUND
Definition: SocialMgr.h:71
@ FRIEND_ADDED_ONLINE
Definition: SocialMgr.h:73
@ FRIEND_SELF
Definition: SocialMgr.h:76
@ FRIEND_LIST_FULL
Definition: SocialMgr.h:68
#define sSocialMgr
Definition: SocialMgr.h:148
@ SOCIAL_FLAG_FRIEND
Definition: SocialMgr.h:40
bool normalizePlayerName(std::string &name)
Definition: ObjectMgr.cpp:206
@ LANG_FRIEND_IGNORE_UNKNOWN
Definition: Language.h:80
@ CONFIG_ALLOW_GM_FRIEND
Definition: IWorld.h:93
@ CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND
Definition: IWorld.h:85
TeamId
TeamId GetTeamId(PvPTeamId teamId)
Realm realm
Definition: World.cpp:112
bool IsGMAccount(uint32 gmlevel)
Definition: AccountMgr.cpp:281
bool IsPlayerAccount(uint32 gmlevel)
Definition: AccountMgr.cpp:276
uint32 GetSecurity(uint32 accountId)
Definition: AccountMgr.cpp:209
Player * FindConnectedPlayer(ObjectGuid const guid)
static TeamId TeamIdForRace(uint8 race)
Definition: Player.cpp:5715
bool IsVisibleGloballyFor(Player const *player) const
Definition: Player.cpp:11196
PlayerSocial * GetSocial()
Definition: Player.h:1121
void SetFriendNote(ObjectGuid friendGuid, std::string note)
Definition: SocialMgr.cpp:105
char const * GetAcoreString(uint32 entry) const
uint32 Realm
Definition: Realm.h:42
RealmHandle Id
Definition: Realm.h:68

◆ HandleAddIgnoreOpcode()

void WorldSession::HandleAddIgnoreOpcode ( WorldPacket recvPacket)

Definition at line 109 of file Socialhandler.cpp.

110{
111 std::string ignoreName = GetAcoreString(LANG_FRIEND_IGNORE_UNKNOWN);
112
113 recv_data >> ignoreName;
114
115 if (!normalizePlayerName(ignoreName))
116 return;
117
118 LOG_DEBUG("network", "WORLD: {} asked to Ignore: '{}'", GetPlayer()->GetName(), ignoreName);
119
120 ObjectGuid ignoreGuid = sCharacterCache->GetCharacterGuidByName(ignoreName);
121 if (!ignoreGuid)
122 return;
123
124 FriendsResult ignoreResult;
125
126 if (ignoreGuid == GetPlayer()->GetGUID()) //not add yourself
127 ignoreResult = FRIEND_IGNORE_SELF;
128 else if (GetPlayer()->GetSocial()->HasIgnore(ignoreGuid))
129 ignoreResult = FRIEND_IGNORE_ALREADY;
130 else
131 {
132 ignoreResult = FRIEND_IGNORE_ADDED;
133
134 // ignore list full
135 if (!GetPlayer()->GetSocial()->AddToSocialList(ignoreGuid, SOCIAL_FLAG_IGNORED))
136 ignoreResult = FRIEND_IGNORE_FULL;
137 }
138
139 sSocialMgr->SendFriendStatus(GetPlayer(), ignoreResult, ignoreGuid, false);
140
141 LOG_DEBUG("network", "WORLD: Sent (SMSG_FRIEND_STATUS)");
142}
@ FRIEND_IGNORE_FULL
Definition: SocialMgr.h:78
@ FRIEND_IGNORE_ADDED
Definition: SocialMgr.h:82
@ FRIEND_IGNORE_SELF
Definition: SocialMgr.h:79
@ FRIEND_IGNORE_ALREADY
Definition: SocialMgr.h:81
@ SOCIAL_FLAG_IGNORED
Definition: SocialMgr.h:41

◆ HandleAlterAppearance()

void WorldSession::HandleAlterAppearance ( WorldPacket recvData)

Definition at line 1503 of file CharacterHandler.cpp.

1504{
1505 LOG_DEBUG("network", "CMSG_ALTER_APPEARANCE");
1506
1507 uint32 Hair, Color, FacialHair, SkinColor;
1508 recvData >> Hair >> Color >> FacialHair >> SkinColor;
1509
1510 BarberShopStyleEntry const* bs_hair = sBarberShopStyleStore.LookupEntry(Hair);
1511
1512 if (!bs_hair || bs_hair->type != 0 || bs_hair->race != _player->getRace() || bs_hair->gender != _player->getGender())
1513 return;
1514
1515 BarberShopStyleEntry const* bs_facialHair = sBarberShopStyleStore.LookupEntry(FacialHair);
1516
1517 if (!bs_facialHair || bs_facialHair->type != 2 || bs_facialHair->race != _player->getRace() || bs_facialHair->gender != _player->getGender())
1518 return;
1519
1520 BarberShopStyleEntry const* bs_skinColor = sBarberShopStyleStore.LookupEntry(SkinColor);
1521
1522 if (bs_skinColor && (bs_skinColor->type != 3 || bs_skinColor->race != _player->getRace() || bs_skinColor->gender != _player->getGender()))
1523 return;
1524
1526 if (!go)
1527 {
1529 data << uint32(2);
1530 SendPacket(&data);
1531 return;
1532 }
1533
1535 {
1537 data << uint32(2);
1538 SendPacket(&data);
1539 return;
1540 }
1541
1542 uint32 cost = _player->GetBarberShopCost(bs_hair->hair_id, Color, bs_facialHair->hair_id, bs_skinColor);
1543
1544 // 0 - ok
1545 // 1, 3 - not enough money
1546 // 2 - you have to seat on barber chair
1547 if (!_player->HasEnoughMoney(cost))
1548 {
1550 data << uint32(1); // no money
1551 SendPacket(&data);
1552 return;
1553 }
1554 else
1555 {
1557 data << uint32(0); // ok
1558 SendPacket(&data);
1559 }
1560
1561 _player->ModifyMoney(-int32(cost)); // it isn't free
1563
1566 _player->SetByteValue(PLAYER_BYTES_2, 0, uint8(bs_facialHair->hair_id));
1567 if (bs_skinColor)
1568 _player->SetByteValue(PLAYER_BYTES, 0, uint8(bs_skinColor->hair_id));
1569
1571
1572 _player->SetStandState(0); // stand up
1573}
DBCStorage< BarberShopStyleEntry > sBarberShopStyleStore(BarberShopStyleEntryfmt)
@ PLAYER_BYTES_2
Definition: UpdateFields.h:182
@ PLAYER_BYTES
Definition: UpdateFields.h:181
@ UNIT_STAND_STATE_SIT_LOW_CHAIR
Definition: Unit.h:57
@ ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP
Definition: DBCEnums.h:168
@ ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER
Definition: DBCEnums.h:183
@ GAMEOBJECT_TYPE_BARBER_CHAIR
@ SMSG_BARBER_SHOP_RESULT
Definition: Opcodes.h:1094
struct GameObjectTemplate::@209::@236 barberChair
void SetByteValue(uint16 index, uint8 offset, uint8 value)
Definition: Object.cpp:750
GameObject * FindNearestGameObjectOfType(GameobjectTypes type, float range) const
Definition: Object.cpp:2410
uint32 GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 newfacialhair, BarberShopStyleEntry const *newSkin=nullptr)
Definition: Player.cpp:12955
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1=0, uint32 miscValue2=0, Unit *unit=nullptr)
uint8 getGender() const
Definition: Unit.h:1426
uint8 getRace(bool original=false) const
Definition: Unit.cpp:21022
uint8 getStandState() const
Definition: Unit.h:1532
void SetStandState(uint8 state)
Definition: Unit.cpp:16812
void SendPacket(WorldPacket const *packet)
Send a packet to the client.

◆ HandleAreaSpiritHealerQueryOpcode()

void WorldSession::HandleAreaSpiritHealerQueryOpcode ( WorldPacket recvData)

Definition at line 1642 of file MiscHandler.cpp.

1643{
1644 LOG_DEBUG("network", "WORLD: CMSG_AREA_SPIRIT_HEALER_QUERY");
1645
1647
1648 ObjectGuid guid;
1649 recv_data >> guid;
1650
1651 Creature* unit = GetPlayer()->GetMap()->GetCreature(guid);
1652 if (!unit)
1653 return;
1654
1655 if (!unit->IsSpiritService()) // it's not spirit service
1656 return;
1657
1658 if (bg)
1659 sBattlegroundMgr->SendAreaSpiritHealerQueryOpcode(_player, bg, guid);
1660
1661 if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId()))
1662 bf->SendAreaSpiritHealerQueryOpcode(_player, guid);
1663}
#define sBattlefieldMgr
#define sBattlegroundMgr
Battleground * GetBattleground(bool create=false) const
Definition: Player.cpp:11913
bool IsSpiritService() const
Definition: Unit.h:1670

◆ HandleAreaSpiritHealerQueueOpcode()

void WorldSession::HandleAreaSpiritHealerQueueOpcode ( WorldPacket recvData)

Definition at line 1665 of file MiscHandler.cpp.

1666{
1667 LOG_DEBUG("network", "WORLD: CMSG_AREA_SPIRIT_HEALER_QUEUE");
1668
1670
1671 ObjectGuid guid;
1672 recv_data >> guid;
1673
1674 Creature* unit = GetPlayer()->GetMap()->GetCreature(guid);
1675 if (!unit)
1676 return;
1677
1678 if (!unit->IsSpiritService()) // it's not spirit service
1679 return;
1680
1681 if (bg)
1683
1684 if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId()))
1685 bf->AddPlayerToResurrectQueue(guid, _player->GetGUID());
1686}
void AddPlayerToResurrectQueue(ObjectGuid npc_guid, ObjectGuid player_guid)

◆ HandleAreaTriggerOpcode()

void WorldSession::HandleAreaTriggerOpcode ( WorldPacket recvPacket)

Definition at line 727 of file MiscHandler.cpp.

728{
729 uint32 triggerId;
730 recv_data >> triggerId;
731
732 LOG_DEBUG("network", "CMSG_AREATRIGGER. Trigger ID: {}", triggerId);
733
734 Player* player = GetPlayer();
735 if (player->IsInFlight())
736 {
737 LOG_DEBUG("network", "HandleAreaTriggerOpcode: Player '{}' ({}) in flight, ignore Area Trigger ID:{}",
738 player->GetName(), player->GetGUID().ToString(), triggerId);
739 return;
740 }
741
742 AreaTrigger const* atEntry = sObjectMgr->GetAreaTrigger(triggerId);
743 if (!atEntry)
744 {
745 LOG_DEBUG("network", "HandleAreaTriggerOpcode: Player '{}' ({}) send unknown (by DBC) Area Trigger ID:{}",
746 player->GetName(), player->GetGUID().ToString(), triggerId);
747 return;
748 }
749
750 uint32 teamFaction = player->GetTeamId(true) == TEAM_ALLIANCE ? FACTION_MASK_ALLIANCE : FACTION_MASK_HORDE;
751 bool isTavernAreatrigger = sObjectMgr->IsTavernAreaTrigger(triggerId, teamFaction);
752 if (!player->IsInAreaTriggerRadius(atEntry, isTavernAreatrigger ? 5.f : 0.f))
753 {
754 LOG_DEBUG("network", "HandleAreaTriggerOpcode: Player {} ({}) too far (trigger map: {} player map: {}), ignore Area Trigger ID: {}",
755 player->GetName(), player->GetGUID().ToString(), atEntry->map, player->GetMapId(), triggerId);
756 return;
757 }
758
759 if (player->isDebugAreaTriggers)
761
762 if (sScriptMgr->OnAreaTrigger(player, atEntry))
763 return;
764
765 if (player->IsAlive())
766 if (uint32 questId = sObjectMgr->GetQuestForAreaTrigger(triggerId))
767 if (player->GetQuestStatus(questId) == QUEST_STATUS_INCOMPLETE)
768 player->AreaExploredOrEventHappens(questId);
769
770 if (isTavernAreatrigger)
771 {
772 // set resting flag we are in the inn
773 player->SetRestFlag(REST_FLAG_IN_TAVERN, atEntry->entry);
774
775 if (sWorld->IsFFAPvPRealm())
776 {
778 {
780 sScriptMgr->OnFfaPvpStateUpdate(player, false);
781
782 }
783 }
784 return;
785 }
786
787 if (Battleground* bg = player->GetBattleground())
788 if (bg->GetStatus() == STATUS_IN_PROGRESS)
789 {
790 bg->HandleAreaTrigger(player, triggerId);
791 return;
792 }
793
794 if (OutdoorPvP* pvp = player->GetOutdoorPvP())
795 if (pvp->HandleAreaTrigger(_player, triggerId))
796 return;
797
798 AreaTriggerTeleport const* at = sObjectMgr->GetAreaTriggerTeleport(triggerId);
799 if (!at)
800 return;
801
802 bool teleported = false;
803 if (player->GetMapId() != at->target_mapId)
804 {
805 if (Map::EnterState denyReason = sMapMgr->PlayerCannotEnter(at->target_mapId, player, false))
806 {
807 bool reviveAtTrigger = false; // should we revive the player if he is trying to enter the correct instance?
808 switch (denyReason)
809 {
815 reviveAtTrigger = true;
816 break;
817 default:
818 break;
819 }
820
821 if (reviveAtTrigger) // check if the player is touching the areatrigger leading to the map his corpse is on
822 {
823 if (!player->IsAlive() && player->HasCorpse())
824 {
825 if (player->GetCorpseLocation().GetMapId() == at->target_mapId)
826 {
827 player->ResurrectPlayer(0.5f);
828 player->SpawnCorpseBones();
829 }
830 }
831 }
832
833 return;
834 }
835
836 if (Group* group = player->GetGroup())
837 if (group->isLFGGroup() && player->GetMap()->IsDungeon())
838 teleported = player->TeleportToEntryPoint();
839 }
840
841 if (!teleported)
843}
@ STATUS_IN_PROGRESS
Definition: Battleground.h:197
@ UNIT_FIELD_BYTES_2
Definition: UpdateFields.h:161
@ TELE_TO_NOT_LEAVE_TRANSPORT
Definition: Player.h:815
@ REST_FLAG_IN_TAVERN
Definition: Player.h:807
@ UNIT_BYTE2_FLAG_FFA_PVP
Definition: Unit.h:138
#define sMapMgr
Definition: MapMgr.h:212
@ LANG_DEBUG_AREATRIGGER_REACHED
Definition: Language.h:954
@ QUEST_STATUS_INCOMPLETE
Definition: QuestDef.h:103
#define sScriptMgr
Definition: ScriptMgr.h:2690
@ FACTION_MASK_ALLIANCE
Definition: DBCEnums.h:343
@ FACTION_MASK_HORDE
Definition: DBCEnums.h:344
@ TEAM_ALLIANCE
void PSendSysMessage(char const *fmt, Args &&... args)
Definition: Chat.h:60
void RemoveByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition: Object.cpp:930
bool HasByteFlag(uint16 index, uint8 offset, uint8 flag) const
Definition: Object.cpp:949
uint32 GetMapId() const
Definition: Position.h:276
void SetRestFlag(RestFlag restFlag, uint32 triggerId=0)
Definition: Player.cpp:15839
TeamId GetTeamId(bool original=false) const
Definition: Player.h:2058
void SpawnCorpseBones(bool triggerSave=true)
Definition: Player.cpp:4571
bool HasCorpse() const
Definition: Player.h:1988
bool TeleportToEntryPoint()
Definition: Player.cpp:1578
OutdoorPvP * GetOutdoorPvP() const
Definition: Player.cpp:12222
WorldLocation GetCorpseLocation() const
Definition: Player.h:1989
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options=0, Unit *target=nullptr, bool newInstance=false)
Definition: Player.cpp:1311
void AreaExploredOrEventHappens(uint32 questId)
QuestStatus GetQuestStatus(uint32 quest_id) const
bool isDebugAreaTriggers
Definition: Player.h:2501
bool IsInAreaTriggerRadius(AreaTrigger const *trigger, float delta=0.f) const
Definition: Player.cpp:2145
void ResurrectPlayer(float restore_percent, bool applySickness=false)
Definition: Player.cpp:4359
bool IsInFlight() const
Definition: Unit.h:1673
float target_Orientation
Definition: ObjectMgr.h:417
uint32 entry
Definition: ObjectMgr.h:422
uint32 map
Definition: ObjectMgr.h:423
bool IsDungeon() const
Definition: Map.h:447
EnterState
Definition: Map.h:422
@ CANNOT_ENTER_TOO_MANY_INSTANCES
Definition: Map.h:431
@ CANNOT_ENTER_MAX_PLAYERS
Definition: Map.h:432
@ CANNOT_ENTER_ZONE_IN_COMBAT
Definition: Map.h:433
@ CANNOT_ENTER_INSTANCE_BIND_MISMATCH
Definition: Map.h:430
@ CANNOT_ENTER_NOT_IN_RAID
Definition: Map.h:428

◆ HandleArenaTeamAcceptOpcode()

void WorldSession::HandleArenaTeamAcceptOpcode ( WorldPacket recvData)

Definition at line 159 of file ArenaTeamHandler.cpp.

160{
161 LOG_DEBUG("network", "CMSG_ARENA_TEAM_ACCEPT"); // empty opcode
162
163 ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(_player->GetArenaTeamIdInvited());
164 if (!arenaTeam)
165 return;
166
167 // Check if player is already in another team of the same size
168 if (_player->GetArenaTeamId(arenaTeam->GetSlot()))
169 {
171 return;
172 }
173
174 // Only allow members of the other faction to join the team if cross faction interaction is enabled
175 if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && _player->GetTeamId() != sCharacterCache->GetCharacterTeamByGuid(arenaTeam->GetCaptain()))
176 {
178 return;
179 }
180
181 // Add player to team
182 if (!arenaTeam->AddMember(_player->GetGUID()))
183 {
185 return;
186 }
187
188 // Broadcast event
189 arenaTeam->BroadcastEvent(ERR_ARENA_TEAM_JOIN_SS, _player->GetGUID(), 2, _player->GetName().c_str(), arenaTeam->GetName(), "");
190}
@ ERR_ARENA_TEAM_CREATE_S
Definition: ArenaTeam.h:33
@ ERR_ARENA_TEAM_INTERNAL
Definition: ArenaTeam.h:41
@ ERR_ALREADY_IN_ARENA_TEAM
Definition: ArenaTeam.h:42
@ ERR_ARENA_TEAM_NOT_ALLIED
Definition: ArenaTeam.h:53
@ ERR_ARENA_TEAM_JOIN_SS
Definition: ArenaTeam.h:64
#define sArenaTeamMgr
Definition: ArenaTeamMgr.h:67
@ CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD
Definition: IWorld.h:81
ObjectGuid GetCaptain() const
Definition: ArenaTeam.h:154
uint8 GetSlot() const
Definition: ArenaTeam.h:151
void BroadcastEvent(ArenaTeamEvents event, ObjectGuid guid, uint8 strCount, std::string const &str1, std::string const &str2, std::string const &str3)
Definition: ArenaTeam.cpp:570
bool AddMember(ObjectGuid playerGuid)
Definition: ArenaTeam.cpp:89
std::string const & GetName() const
Definition: ArenaTeam.h:155
uint32 GetArenaTeamId(uint8 slot) const
Definition: Player.cpp:15900
uint32 GetArenaTeamIdInvited()
Definition: Player.h:1867
void SendArenaTeamCommandResult(uint32 team_action, std::string const &team, std::string const &player, uint32 error_id=0)

◆ HandleArenaTeamDeclineOpcode()

void WorldSession::HandleArenaTeamDeclineOpcode ( WorldPacket recvData)

Definition at line 192 of file ArenaTeamHandler.cpp.

193{
194 LOG_DEBUG("network", "CMSG_ARENA_TEAM_DECLINE"); // empty opcode
195
196 // Remove invite from player
198}
void SetArenaTeamIdInvited(uint32 ArenaTeamId)
Definition: Player.h:1866

◆ HandleArenaTeamDisbandOpcode()

void WorldSession::HandleArenaTeamDisbandOpcode ( WorldPacket recvData)

Definition at line 257 of file ArenaTeamHandler.cpp.

258{
259 LOG_DEBUG("network", "CMSG_ARENA_TEAM_DISBAND");
260
261 uint32 arenaTeamId;
262 recvData >> arenaTeamId;
263
264 if (ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId))
265 {
266 // Only captain can disband the team
267 if (arenaTeam->GetCaptain() != _player->GetGUID())
268 return;
269
270 // Teams cannot be disbanded during queues
272 {
273 GroupQueueInfo ginfo;
274 BattlegroundQueue& queue = sBattlegroundMgr->GetBattlegroundQueue(bgQueue);
275 if (queue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo))
277 return;
278 }
279
280 // Teams cannot be disbanded during fights
281 if (arenaTeam->IsFighting())
282 return;
283
284 arenaTeam->Disband(this);
285 delete arenaTeam;
286 }
287}
@ BATTLEGROUND_AA
BattlegroundQueueTypeId
static BattlegroundQueueTypeId BGQueueTypeId(BattlegroundTypeId bgTypeId, uint8 arenaType)
uint32 IsInvitedToBGInstanceGUID
bool GetPlayerGroupInfoData(ObjectGuid guid, GroupQueueInfo *ginfo)

◆ HandleArenaTeamInviteOpcode()

void WorldSession::HandleArenaTeamInviteOpcode ( WorldPacket recvData)

Definition at line 75 of file ArenaTeamHandler.cpp.

76{
77 LOG_DEBUG("network", "CMSG_ARENA_TEAM_INVITE");
78
79 uint32 arenaTeamId; // arena team id
80 std::string invitedName;
81
82 Player* player = nullptr;
83
84 recvData >> arenaTeamId >> invitedName;
85
86 if (!invitedName.empty())
87 {
88 if (!normalizePlayerName(invitedName))
89 return;
90
91 player = ObjectAccessor::FindPlayerByName(invitedName, false);
92 }
93
94 if (!player)
95 {
97 return;
98 }
99
100 if (player->getLevel() < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
101 {
103 return;
104 }
105
106 ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId);
107 if (!arenaTeam)
108 {
110 return;
111 }
112
113 if (GetPlayer()->GetArenaTeamId(arenaTeam->GetSlot()) != arenaTeamId)
114 {
116 return;
117 }
118
119 // OK result but don't send invite
120 if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUID()))
121 return;
122
123 if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && player->GetTeamId() != GetPlayer()->GetTeamId())
124 {
126 return;
127 }
128
129 if (player->GetArenaTeamId(arenaTeam->GetSlot()))
130 {
132 return;
133 }
134
135 if (player->GetArenaTeamIdInvited())
136 {
138 return;
139 }
140
141 if (arenaTeam->GetMembersSize() >= arenaTeam->GetType() * 2)
142 {
144 return;
145 }
146
147 LOG_DEBUG("bg.battleground", "Player {} Invited {} to Join his ArenaTeam", GetPlayer()->GetName(), invitedName);
148
149 player->SetArenaTeamIdInvited(arenaTeam->GetId());
150
151 WorldPacket data(SMSG_ARENA_TEAM_INVITE, (8 + 10));
152 data << GetPlayer()->GetName();
153 data << arenaTeam->GetName();
154 player->GetSession()->SendPacket(&data);
155
156 LOG_DEBUG("network", "WORLD: Sent SMSG_ARENA_TEAM_INVITE");
157}
@ ERR_ARENA_TEAM_INVITE_SS
Definition: ArenaTeam.h:34
@ ERR_ARENA_TEAM_TOO_MANY_MEMBERS_S
Definition: ArenaTeam.h:57
@ ERR_ALREADY_IN_ARENA_TEAM_S
Definition: ArenaTeam.h:43
@ ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM
Definition: ArenaTeam.h:50
@ ERR_ARENA_TEAM_PERMISSIONS
Definition: ArenaTeam.h:49
@ ERR_ARENA_TEAM_TARGET_TOO_LOW_S
Definition: ArenaTeam.h:55
@ ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S
Definition: ArenaTeam.h:52
@ ERR_ALREADY_INVITED_TO_ARENA_TEAM_S
Definition: ArenaTeam.h:45
@ CONFIG_MAX_PLAYER_LEVEL
Definition: IWorld.h:229
@ SMSG_ARENA_TEAM_INVITE
Definition: Opcodes.h:878
Player * FindPlayerByName(std::string const &name, bool checkInWorld=true)
size_t GetMembersSize() const
Definition: ArenaTeam.h:170
uint32 GetType() const
Definition: ArenaTeam.h:150
uint32 GetId() const
Definition: ArenaTeam.h:149
bool HasIgnore(ObjectGuid ignore_guid) const
Definition: SocialMgr.cpp:193

◆ HandleArenaTeamLeaderOpcode()

void WorldSession::HandleArenaTeamLeaderOpcode ( WorldPacket recvData)

Definition at line 354 of file ArenaTeamHandler.cpp.

355{
356 LOG_DEBUG("network", "CMSG_ARENA_TEAM_LEADER");
357
358 uint32 arenaTeamId;
359 std::string name;
360
361 recvData >> arenaTeamId;
362 recvData >> name;
363
364 // Check for valid arena team
365 ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId);
366 if (!arenaTeam)
367 return;
368
369 // Only captain can pass leadership
370 if (arenaTeam->GetCaptain() != _player->GetGUID())
371 {
373 return;
374 }
375
376 if (!normalizePlayerName(name))
377 return;
378
379 // Check if team member exists
380 ArenaTeamMember* member = arenaTeam->GetMember(name);
381 if (!member)
382 {
384 return;
385 }
386
387 // Check if the target is already team captain
388 if (arenaTeam->GetCaptain() == member->Guid)
389 return;
390
391 arenaTeam->SetCaptain(member->Guid);
392
393 // Broadcast event
394 arenaTeam->BroadcastEvent(ERR_ARENA_TEAM_LEADER_CHANGED_SSS, ObjectGuid::Empty, 3, _player->GetName().c_str(), name, arenaTeam->GetName());
395}
@ ERR_ARENA_TEAM_LEADER_CHANGED_SSS
Definition: ArenaTeam.h:68
ObjectGuid Guid
Definition: ArenaTeam.h:110
void SetCaptain(ObjectGuid guid)
Definition: ArenaTeam.cpp:295
ArenaTeamMember * GetMember(ObjectGuid guid)
Definition: ArenaTeam.cpp:1002

◆ HandleArenaTeamLeaveOpcode()

void WorldSession::HandleArenaTeamLeaveOpcode ( WorldPacket recvData)

Definition at line 200 of file ArenaTeamHandler.cpp.

201{
202 LOG_DEBUG("network", "CMSG_ARENA_TEAM_LEAVE");
203
204 uint32 arenaTeamId;
205 recvData >> arenaTeamId;
206
207 ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId);
208 if (!arenaTeam)
209 return;
210
211 // Disallow leave team while in arena
212 if (arenaTeam->IsFighting())
213 {
215 return;
216 }
217
218 // Team captain can't leave the team if other members are still present
219 if (_player->GetGUID() == arenaTeam->GetCaptain() && arenaTeam->GetMembersSize() > 1)
220 {
222 return;
223 }
224
225 // Player cannot be removed during queues
227 {
228 GroupQueueInfo ginfo;
229 BattlegroundQueue& queue = sBattlegroundMgr->GetBattlegroundQueue(bgQueue);
230 if (queue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo))
231 {
233 {
235 return;
236 }
237 }
238 }
239
240 // If team consists only of the captain, disband the team
241 if (_player->GetGUID() == arenaTeam->GetCaptain())
242 {
243 arenaTeam->Disband(this);
244 delete arenaTeam;
245 return;
246 }
247 else
248 arenaTeam->DelMember(_player->GetGUID(), true);
249
250 // Broadcast event
251 arenaTeam->BroadcastEvent(ERR_ARENA_TEAM_LEAVE_SS, _player->GetGUID(), 2, _player->GetName().c_str(), arenaTeam->GetName(), "");
252
253 // Inform player who left
255}
@ ERR_ARENA_TEAM_QUIT_S
Definition: ArenaTeam.h:35
@ ERR_ARENA_TEAMS_LOCKED
Definition: ArenaTeam.h:59
@ ERR_ARENA_TEAM_LEADER_LEAVE_S
Definition: ArenaTeam.h:48
@ ERR_ARENA_TEAM_LEAVE_SS
Definition: ArenaTeam.h:65
void Disband(WorldSession *session)
Definition: ArenaTeam.cpp:383
void DelMember(ObjectGuid guid, bool cleanDb)
Definition: ArenaTeam.cpp:324
bool IsFighting() const
Definition: ArenaTeam.cpp:987

◆ HandleArenaTeamQueryOpcode()

void WorldSession::HandleArenaTeamQueryOpcode ( WorldPacket recvData)

Definition at line 50 of file ArenaTeamHandler.cpp.

51{
52 LOG_DEBUG("network", "WORLD: Received CMSG_ARENA_TEAM_QUERY");
53
54 uint32 arenaTeamId;
55 recvData >> arenaTeamId;
56
57 if (ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId))
58 {
59 arenaTeam->Query(this);
60 arenaTeam->SendStats(this);
61 }
62}

◆ HandleArenaTeamRemoveOpcode()

void WorldSession::HandleArenaTeamRemoveOpcode ( WorldPacket recvData)

Definition at line 289 of file ArenaTeamHandler.cpp.

290{
291 LOG_DEBUG("network", "CMSG_ARENA_TEAM_REMOVE");
292
293 uint32 arenaTeamId;
294 std::string name;
295
296 recvData >> arenaTeamId;
297 recvData >> name;
298
299 // Check for valid arena team
300 ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId);
301 if (!arenaTeam)
302 return;
303
304 // Only captain can remove members
305 if (arenaTeam->GetCaptain() != _player->GetGUID())
306 {
308 return;
309 }
310
311 if (!normalizePlayerName(name))
312 return;
313
314 // Check if team member exists
315 ArenaTeamMember* member = arenaTeam->GetMember(name);
316 if (!member)
317 {
319 return;
320 }
321
322 // Captain cannot be removed
323 if (arenaTeam->GetCaptain() == member->Guid)
324 {
326 return;
327 }
328
329 // Team member cannot be removed during queues
331 {
332 GroupQueueInfo ginfo;
333 BattlegroundQueue& queue = sBattlegroundMgr->GetBattlegroundQueue(bgQueue);
334 if (queue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo))
335 {
337 {
339 return;
340 }
341 }
342 }
343
344 // Player cannot be removed during fights
345 if (arenaTeam->IsFighting())
346 return;
347
348 arenaTeam->DelMember(member->Guid, true);
349
350 // Broadcast event
352}
@ ERR_ARENA_TEAM_REMOVE_SSS
Definition: ArenaTeam.h:66

◆ HandleArenaTeamRosterOpcode()

void WorldSession::HandleArenaTeamRosterOpcode ( WorldPacket recvData)

Definition at line 64 of file ArenaTeamHandler.cpp.

65{
66 LOG_DEBUG("network", "WORLD: Received CMSG_ARENA_TEAM_ROSTER");
67
68 uint32 arenaTeamId; // arena team id
69 recvData >> arenaTeamId;
70
71 if (ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId))
72 arenaTeam->Roster(this);
73}

◆ HandleAttackStopOpcode()

void WorldSession::HandleAttackStopOpcode ( WorldPacket recvPacket)

Definition at line 69 of file CombatHandler.cpp.

70{
72}
bool AttackStop()
Definition: Unit.cpp:10356

◆ HandleAttackSwingOpcode()

void WorldSession::HandleAttackSwingOpcode ( WorldPacket recvPacket)

Client explicitly checks the following before sending CMSG_ATTACKSWING packet, so we'll place the same check here. Note that it might be possible to reuse this snippet in other places as well.

Definition at line 29 of file CombatHandler.cpp.

30{
31 ObjectGuid guid;
32 recvData >> guid;
33
34 LOG_DEBUG("network", "WORLD: Recvd CMSG_ATTACKSWING: {}", guid.ToString());
35
36 Unit* pEnemy = ObjectAccessor::GetUnit(*_player, guid);
37
38 if (!pEnemy)
39 {
40 // stop attack state at client
41 SendAttackStop(nullptr);
42 return;
43 }
44
45 if (!_player->IsValidAttackTarget(pEnemy))
46 {
47 // stop attack state at client
48 SendAttackStop(pEnemy);
49 return;
50 }
51
55 if (Vehicle* vehicle = _player->GetVehicle())
56 {
57 VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(_player);
58 ASSERT(seat);
60 {
61 SendAttackStop(pEnemy);
62 return;
63 }
64 }
65
66 _player->Attack(pEnemy, true);
67}
#define ASSERT
Definition: Errors.h:68
@ VEHICLE_SEAT_FLAG_CAN_ATTACK
Definition: DBCEnums.h:463
Unit * GetUnit(WorldObject const &, ObjectGuid const guid)
Definition: Unit.h:1290
bool IsValidAttackTarget(Unit const *target) const
Definition: Unit.cpp:13764
bool Attack(Unit *victim, bool meleeAttack)
Definition: Unit.cpp:10233
void SendAttackStop(Unit const *enemy)

◆ HandleAuctionHelloOpcode()

void WorldSession::HandleAuctionHelloOpcode ( WorldPacket recvPacket)

Definition at line 34 of file AuctionHouseHandler.cpp.

35{
36 ObjectGuid guid; //NPC guid
37 recvData >> guid;
38
40 if (!unit)
41 {
42 LOG_DEBUG("network", "WORLD: HandleAuctionHelloOpcode - Unit ({}) not found or you can't interact with him.", guid.ToString());
43 return;
44 }
45
46 // remove fake death
47 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
49
50 SendAuctionHello(guid, unit);
51}
@ UNIT_NPC_FLAG_AUCTIONEER
Definition: Unit.h:537
@ UNIT_STATE_DIED
Definition: Unit.h:325
@ SPELL_AURA_FEIGN_DEATH
void RemoveAurasByType(AuraType auraType, ObjectGuid casterGUID=ObjectGuid::Empty, Aura *except=nullptr, bool negative=true, bool positive=true)
Definition: Unit.cpp:5013
void SendAuctionHello(ObjectGuid guid, Creature *unit)

◆ HandleAuctionListBidderItems()

void WorldSession::HandleAuctionListBidderItems ( WorldPacket recvData)

Definition at line 598 of file AuctionHouseHandler.cpp.

599{
600 LOG_DEBUG("network", "WORLD: Received CMSG_AUCTION_LIST_BIDDER_ITEMS");
601
602 ObjectGuid guid; //NPC guid
603 uint32 listfrom; //page of auctions
604 uint32 outbiddedCount; //count of outbidded auctions
605
606 recvData >> guid;
607 recvData >> listfrom; // not used in fact (this list not have page control in client)
608 recvData >> outbiddedCount;
609 if (recvData.size() != (16 + outbiddedCount * 4))
610 {
611 LOG_ERROR("network.opcode", "Client sent bad opcode!!! with count: {} and size : {} (must be: {})", outbiddedCount, (unsigned long)recvData.size(), (16 + outbiddedCount * 4));
612 outbiddedCount = 0;
613 }
614
616 if (!creature)
617 {
618 LOG_DEBUG("network", "WORLD: HandleAuctionListBidderItems - Unit ({}) not found or you can't interact with him.", guid.ToString());
619 recvData.rfinish();
620 return;
621 }
622
623 // remove fake death
624 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
626
627 AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->GetFaction());
628
629 WorldPacket data(SMSG_AUCTION_BIDDER_LIST_RESULT, (4 + 4 + 4) + 30000); // pussywizard: ensure there is enough memory
630 Player* player = GetPlayer();
631 data << (uint32) 0; //add 0 as count
632 uint32 count = 0;
633 uint32 totalcount = 0;
634 while (outbiddedCount > 0) //add all data, which client requires
635 {
636 --outbiddedCount;
637 uint32 outbiddedAuctionId;
638 recvData >> outbiddedAuctionId;
639 AuctionEntry* auction = auctionHouse->GetAuction(outbiddedAuctionId);
640 if (auction && auction->BuildAuctionInfo(data))
641 {
642 ++totalcount;
643 ++count;
644 }
645 }
646
647 auctionHouse->BuildListBidderItems(data, player, count, totalcount);
648 data.put<uint32>(0, count); // add count to placeholder
649 data << totalcount;
650 data << (uint32)300; //unk 2.3.0
651 SendPacket(&data);
652}
#define sAuctionMgr
@ SMSG_AUCTION_BIDDER_LIST_RESULT
Definition: Opcodes.h:643
bool BuildAuctionInfo(WorldPacket &data) const
void BuildListBidderItems(WorldPacket &data, Player *player, uint32 &count, uint32 &totalcount)
AuctionEntry * GetAuction(uint32 id) const
uint32 GetFaction() const
Definition: Unit.h:1493
void rfinish()
Definition: ByteBuffer.h:325
size_t size() const
Definition: ByteBuffer.h:444

◆ HandleAuctionListItems()

void WorldSession::HandleAuctionListItems ( WorldPacket recvData)

Definition at line 710 of file AuctionHouseHandler.cpp.

711{
712 LOG_DEBUG("network", "WORLD: Received CMSG_AUCTION_LIST_ITEMS");
713
714 std::string searchedname;
715 uint8 levelmin, levelmax, usable;
716 uint32 listfrom, auctionSlotID, auctionMainCategory, auctionSubCategory, quality;
717 ObjectGuid guid;
718
719 recvData >> guid;
720 recvData >> listfrom; // start, used for page control listing by 50 elements
721 recvData >> searchedname;
722
723 recvData >> levelmin >> levelmax;
724 recvData >> auctionSlotID >> auctionMainCategory >> auctionSubCategory;
725 recvData >> quality >> usable;
726
727 //recvData.read_skip<uint8>(); // pussywizard: this is the getAll option
728 uint8 getAll;
729 recvData >> getAll;
730
731 // Read sort block
732 uint8 sortOrderCount;
733 recvData >> sortOrderCount;
734 AuctionSortOrderVector sortOrder;
735 for (uint8 i = 0; i < sortOrderCount; i++)
736 {
737 uint8 sortMode;
738 uint8 isDesc;
739 recvData >> sortMode;
740 recvData >> isDesc;
741 AuctionSortInfo sortInfo;
742 sortInfo.isDesc = (isDesc == 1);
743 sortInfo.sortOrder = static_cast<AuctionSortOrder>(sortMode);
744 sortOrder.push_back(std::move(sortInfo));
745 }
746
747 // remove fake death
749 {
751 }
752
753 // pussywizard:
754 const uint32 delay = 2000;
755 const uint32 now = GameTime::GetGameTimeMS().count();
757 if (diff > delay)
758 {
759 diff = delay;
760 }
761 _lastAuctionListItemsMSTime = now + delay - diff;
762 std::lock_guard<std::mutex> guard(AsyncAuctionListingMgr::GetTempLock());
763 AsyncAuctionListingMgr::GetTempList().push_back(AuctionListItemsDelayEvent(delay - diff, _player->GetGUID(), guid, searchedname, listfrom, levelmin, levelmax, usable, auctionSlotID,
764 auctionMainCategory, auctionSubCategory, quality, getAll, sortOrder));
765}
uint32 getMSTimeDiff(uint32 oldMSTime, uint32 newMSTime)
Definition: Timer.h:110
AuctionSortOrder
std::vector< AuctionSortInfo > AuctionSortOrderVector
Milliseconds GetGameTimeMS()
Definition: GameTime.cpp:43
AuctionSortOrder sortOrder
bool HasUnitState(const uint32 f) const
Definition: Unit.h:1398
static std::mutex & GetTempLock()
static std::list< AuctionListItemsDelayEvent > & GetTempList()

◆ HandleAuctionListOwnerItems()

void WorldSession::HandleAuctionListOwnerItems ( WorldPacket recvData)

Definition at line 655 of file AuctionHouseHandler.cpp.

656{
657 // prevent crash caused by malformed packet
658 ObjectGuid guid;
659 uint32 listfrom;
660
661 recvData >> guid;
662 recvData >> listfrom; // not used in fact (this list does not have page control in client)
663
664 // pussywizard:
665 const uint32 delay = 4500;
666 const uint32 now = GameTime::GetGameTimeMS().count();
667 if (_lastAuctionListOwnerItemsMSTime > now) // list is pending
668 return;
670 if (diff > delay)
671 diff = delay;
672
673 _lastAuctionListOwnerItemsMSTime = now + delay; // set longest possible here, actual exectuing will change this to getMSTime of that moment
675}
void AddEvent(BasicEvent *Event, uint64 e_time, bool set_addtime=true)
uint64 CalculateTime(uint64 t_offset) const
EventProcessor m_Events
Definition: Unit.h:2091

◆ HandleAuctionListOwnerItemsEvent()

void WorldSession::HandleAuctionListOwnerItemsEvent ( ObjectGuid  creatureGuid)

Definition at line 677 of file AuctionHouseHandler.cpp.

678{
679 LOG_DEBUG("network", "WORLD: Received CMSG_AUCTION_LIST_OWNER_ITEMS");
680
682
684 if (!creature)
685 {
686 LOG_DEBUG("network", "WORLD: HandleAuctionListOwnerItems - Unit ({}) not found or you can't interact with him.", creatureGuid.ToString());
687 return;
688 }
689
690 // remove fake death
691 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
693
694 AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->GetFaction());
695
696 WorldPacket data(SMSG_AUCTION_OWNER_LIST_RESULT, (4 + 4 + 4) + 60000); // pussywizard: ensure there is enough memory
697 data << (uint32) 0; // amount place holder
698
699 uint32 count = 0;
700 uint32 totalcount = 0;
701
702 auctionHouse->BuildListOwnerItems(data, _player, count, totalcount);
703 data.put<uint32>(0, count);
704 data << (uint32) totalcount;
705 data << (uint32) 0;
706 SendPacket(&data);
707}
@ SMSG_AUCTION_OWNER_LIST_RESULT
Definition: Opcodes.h:635
void BuildListOwnerItems(WorldPacket &data, Player *player, uint32 &count, uint32 &totalcount)

◆ HandleAuctionListPendingSales()

void WorldSession::HandleAuctionListPendingSales ( WorldPacket recvData)

Definition at line 767 of file AuctionHouseHandler.cpp.

768{
769 LOG_DEBUG("network", "WORLD: Received CMSG_AUCTION_LIST_PENDING_SALES");
770
771 recvData.read_skip<uint64>();
772
773 uint32 count = 0;
774
776 data << uint32(count); // count
777 /*for (uint32 i = 0; i < count; ++i)
778 {
779 data << ""; // string
780 data << ""; // string
781 data << uint32(0);
782 data << uint32(0);
783 data << float(0);
784 }*/
785 SendPacket(&data);
786}
@ SMSG_AUCTION_LIST_PENDING_SALES
Definition: Opcodes.h:1198
void read_skip()
Definition: ByteBuffer.h:339

◆ HandleAuctionPlaceBid()

void WorldSession::HandleAuctionPlaceBid ( WorldPacket recvData)

Definition at line 396 of file AuctionHouseHandler.cpp.

397{
398 LOG_DEBUG("network", "WORLD: Received CMSG_AUCTION_PLACE_BID");
399
400 ObjectGuid auctioneer;
401 uint32 auctionId;
402 uint32 price;
403 recvData >> auctioneer;
404 recvData >> auctionId >> price;
405
406 if (!auctionId || !price)
407 return; //check for cheaters
408
410 if (!creature)
411 {
412 LOG_DEBUG("network", "WORLD: HandleAuctionPlaceBid - Unit ({}) not found or you can't interact with him.", auctioneer.ToString());
413 return;
414 }
415
416 // remove fake death
417 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
419
420 AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->GetFaction());
421
422 AuctionEntry* auction = auctionHouse->GetAuction(auctionId);
423 Player* player = GetPlayer();
424
425 if (!auction || auction->owner == player->GetGUID())
426 {
427 //you cannot bid your own auction:
429 return;
430 }
431
432 // impossible have online own another character (use this for speedup check in case online owner)
433 Player* auction_owner = ObjectAccessor::FindConnectedPlayer(auction->owner);
434 if (!auction_owner && sCharacterCache->GetCharacterAccountIdByGuid(auction->owner) == GetAccountId())
435 {
436 //you cannot bid your another character auction:
438 return;
439 }
440
441 // cheating
442 if (price <= auction->bid || price < auction->startbid)
443 return;
444
445 // price too low for next bid if not buyout
446 if ((price < auction->buyout || auction->buyout == 0) &&
447 price < auction->bid + auction->GetAuctionOutBid())
448 {
449 //auction has already higher bid, client tests it!
450 return;
451 }
452
453 if (!player->HasEnoughMoney(price))
454 {
455 //you don't have enought money!, client tests!
456 //SendAuctionCommandResult(auction->auctionId, AUCTION_PLACE_BID, ???);
457 return;
458 }
459
460 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
461
462 if (price < auction->buyout || auction->buyout == 0)
463 {
464 if (auction->bidder)
465 {
466 if (auction->bidder == player->GetGUID())
467 player->ModifyMoney(-int32(price - auction->bid));
468 else
469 {
470 // mail to last bidder and return money
471 sAuctionMgr->SendAuctionOutbiddedMail(auction, price, GetPlayer(), trans);
472 player->ModifyMoney(-int32(price));
473 }
474 }
475 else
476 player->ModifyMoney(-int32(price));
477
478 auction->bidder = player->GetGUID();
479 auction->bid = price;
481
483 stmt->SetData(0, auction->bidder.GetCounter());
484 stmt->SetData(1, auction->bid);
485 stmt->SetData(2, auction->Id);
486 trans->Append(stmt);
487
489 }
490 else
491 {
492 //buyout:
493 if (player->GetGUID() == auction->bidder)
494 player->ModifyMoney(-int32(auction->buyout - auction->bid));
495 else
496 {
497 player->ModifyMoney(-int32(auction->buyout));
498 if (auction->bidder) //buyout for bidded auction ..
499 sAuctionMgr->SendAuctionOutbiddedMail(auction, auction->buyout, GetPlayer(), trans);
500 }
501 auction->bidder = player->GetGUID();
502 auction->bid = auction->buyout;
504
505 //- Mails must be under transaction control too to prevent data loss
506 sAuctionMgr->SendAuctionSalePendingMail(auction, trans);
507 sAuctionMgr->SendAuctionSuccessfulMail(auction, trans);
508 sAuctionMgr->SendAuctionWonMail(auction, trans);
509 sScriptMgr->OnAuctionSuccessful(auctionHouse, auction);
510
512
513 auction->DeleteFromDB(trans);
514
515 sAuctionMgr->RemoveAItem(auction->item_guid);
516 auctionHouse->RemoveAuction(auction);
517 }
518 player->SaveInventoryAndGoldToDB(trans);
519 CharacterDatabase.CommitTransaction(trans);
520}
@ CHAR_UPD_AUCTION_BID
@ AUCTION_PLACE_BID
@ ERR_AUCTION_OK
@ ERR_AUCTION_BID_OWN
@ ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID
Definition: DBCEnums.h:197
Acore::Types::is_default< T > SetData(const uint8 index, T value)
uint32 GetAuctionOutBid() const
the sum of outbid is (1% from current bid)*5, if bid is very small, it is 1c
void DeleteFromDB(CharacterDatabaseTransaction trans) const
ObjectGuid bidder
ObjectGuid item_guid
ObjectGuid owner
bool RemoveAuction(AuctionEntry *auction)
void SendAuctionCommandResult(uint32 auctionId, uint32 Action, uint32 ErrorCode, uint32 bidError=0)

◆ HandleAuctionRemoveItem()

void WorldSession::HandleAuctionRemoveItem ( WorldPacket recvData)

Definition at line 523 of file AuctionHouseHandler.cpp.

524{
525 LOG_DEBUG("network", "WORLD: Received CMSG_AUCTION_REMOVE_ITEM");
526
527 ObjectGuid auctioneer;
528 uint32 auctionId;
529 recvData >> auctioneer;
530 recvData >> auctionId;
531
533 if (!creature)
534 {
535 LOG_DEBUG("network", "WORLD: HandleAuctionRemoveItem - Unit ({}) not found or you can't interact with him.", auctioneer.ToString());
536 return;
537 }
538
539 // remove fake death
540 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
542
543 AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->GetFaction());
544
545 AuctionEntry* auction = auctionHouse->GetAuction(auctionId);
546 Player* player = GetPlayer();
547
548 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
549 if (auction && auction->owner == player->GetGUID())
550 {
551 Item* pItem = sAuctionMgr->GetAItem(auction->item_guid);
552 if (pItem)
553 {
554 if (auction->bidder) // If we have a bidder, we have to send him the money he paid
555 {
556 uint32 auctionCut = auction->GetAuctionCut();
557 if (!player->HasEnoughMoney(auctionCut)) //player doesn't have enough money, maybe message needed
558 return;
559 //some auctionBidderNotification would be needed, but don't know that parts..
560 sAuctionMgr->SendAuctionCancelledToBidderMail(auction, trans);
561 player->ModifyMoney(-int32(auctionCut));
562 }
563
564 // item will deleted or added to received mail list
566 .AddItem(pItem)
567 .SendMailTo(trans, player, auction, MAIL_CHECK_MASK_COPIED);
568 }
569 else
570 {
571 LOG_ERROR("network.opcode", "Auction id: {} has non-existed item (item: {})!!!", auction->Id, auction->item_guid.ToString());
573 return;
574 }
575 }
576 else
577 {
579 //this code isn't possible ... maybe there should be assert
580 LOG_ERROR("network.opcode", "CHEATER : {}, he tried to cancel auction (id: {}) of another player, or auction is nullptr", player->GetGUID().ToString(), auctionId);
581 return;
582 }
583
584 //inform player, that auction is removed
586
587 // Now remove the auction
588
589 player->SaveInventoryAndGoldToDB(trans);
590 auction->DeleteFromDB(trans);
591 CharacterDatabase.CommitTransaction(trans);
592
593 sAuctionMgr->RemoveAItem(auction->item_guid);
594 auctionHouse->RemoveAuction(auction);
595}
@ AUCTION_CANCELED
@ AUCTION_CANCEL
@ ERR_AUCTION_DATABASE_ERROR
@ MAIL_CHECK_MASK_COPIED
This mail was returned. Do not allow returning mail back again.
Definition: Mail.h:50
static std::string BuildAuctionMailBody(ObjectGuid guid, uint32 bid, uint32 buyout, uint32 deposit=0, uint32 cut=0, uint32 moneyDelay=0, uint32 eta=0)
std::string BuildAuctionMailSubject(MailAuctionAnswers response) const
uint32 GetAuctionCut() const
void SendMailTo(CharacterDatabaseTransaction trans, MailReceiver const &receiver, MailSender const &sender, MailCheckMask checked=MAIL_CHECK_MASK_NONE, uint32 deliver_delay=0, uint32 custom_expiration=0, bool deleteMailItemsFromDB=false, bool sendMail=true)
Definition: Mail.cpp:186
MailDraft & AddItem(Item *item)
Definition: Mail.cpp:94

◆ HandleAuctionSellItem()

void WorldSession::HandleAuctionSellItem ( WorldPacket recvData)

Definition at line 117 of file AuctionHouseHandler.cpp.

118{
119 ObjectGuid auctioneer;
120 uint32 itemsCount, etime, bid, buyout;
121 recvData >> auctioneer;
122 recvData >> itemsCount;
123
124 ObjectGuid itemGUIDs[MAX_AUCTION_ITEMS]; // 160 slot = 4x 36 slot bag + backpack 16 slot
126 memset(count, 0, sizeof(count));
127
128 if (itemsCount > MAX_AUCTION_ITEMS)
129 {
131 recvData.rfinish();
132 return;
133 }
134
135 for (uint32 i = 0; i < itemsCount; ++i)
136 {
137 recvData >> itemGUIDs[i];
138 recvData >> count[i];
139
140 if (!itemGUIDs[i] || !count[i] || count[i] > 1000)
141 {
142 recvData.rfinish();
143 return;
144 }
145 }
146
147 recvData >> bid;
148 recvData >> buyout;
149 recvData >> etime;
150
151 if (!bid || !etime)
152 return;
153
154 if (bid > MAX_MONEY_AMOUNT || buyout > MAX_MONEY_AMOUNT)
155 {
156 LOG_DEBUG("network", "WORLD: HandleAuctionSellItem - Player {} ({}) attempted to sell item with higher price than max gold amount.",
159 return;
160 }
161
163 if (!creature)
164 {
165 LOG_DEBUG("network", "WORLD: HandleAuctionSellItem - Unit ({}) not found or you can't interact with him.", auctioneer.ToString());
166 return;
167 }
168
169 AuctionHouseEntry const* auctionHouseEntry = AuctionHouseMgr::GetAuctionHouseEntry(creature->GetFaction());
170 if (!auctionHouseEntry)
171 {
172 LOG_DEBUG("network", "WORLD: HandleAuctionSellItem - Unit ({}) has wrong faction.", auctioneer.ToString());
173 return;
174 }
175
176 etime *= MINUTE;
177
178 switch (etime)
179 {
180 case 1*MIN_AUCTION_TIME:
181 case 2*MIN_AUCTION_TIME:
182 case 4*MIN_AUCTION_TIME:
183 break;
184 default:
185 return;
186 }
187
188 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
190
191 Item* items[MAX_AUCTION_ITEMS];
192
193 uint32 finalCount = 0;
194 uint32 itemEntry = 0;
195
196 for (uint32 i = 0; i < itemsCount; ++i)
197 {
198 Item* item = _player->GetItemByGuid(itemGUIDs[i]);
199
200 if (!item)
201 {
203 return;
204 }
205
206 if (itemEntry == 0)
207 itemEntry = item->GetTemplate()->ItemId;
208
209 if (sAuctionMgr->GetAItem(item->GetGUID()) || !item->CanBeTraded() || item->IsNotEmptyBag() ||
211 item->GetCount() < count[i] || itemEntry != item->GetTemplate()->ItemId)
212 {
214 return;
215 }
216
217 items[i] = item;
218 finalCount += count[i];
219 }
220
221 if (!finalCount)
222 {
224 return;
225 }
226
227 // check if there are 2 identical guids, in this case user is most likely cheating
228 for (uint32 i = 0; i < itemsCount - 1; ++i)
229 {
230 for (uint32 j = i + 1; j < itemsCount; ++j)
231 {
232 if (itemGUIDs[i] == itemGUIDs[j])
233 {
235 return;
236 }
237 }
238 }
239
240 for (uint32 i = 0; i < itemsCount; ++i)
241 {
242 Item* item = items[i];
243
244 if (item->GetMaxStackCount() < finalCount)
245 {
247 return;
248 }
249 }
250
251 for (uint32 i = 0; i < itemsCount; ++i)
252 {
253 Item* item = items[i];
254
255 uint32 auctionTime = uint32(etime * sWorld->getRate(RATE_AUCTION_TIME));
256 AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->GetFaction());
257
258 uint32 deposit = sAuctionMgr->GetAuctionDeposit(auctionHouseEntry, etime, item, finalCount);
259 if (!_player->HasEnoughMoney(deposit))
260 {
262 return;
263 }
264
265 _player->ModifyMoney(-int32(deposit));
266
267 AuctionEntry* AH = new AuctionEntry;
268 AH->Id = sObjectMgr->GenerateAuctionID();
269
272 else
273 {
274 CreatureData const* auctioneerData = sObjectMgr->GetCreatureData(creature->GetSpawnId());
275 if (!auctioneerData)
276 {
277 LOG_ERROR("network.opcode", "Data for auctioneer not found ({})", auctioneer.ToString());
278 return;
279 }
280
281 CreatureTemplate const* auctioneerInfo = sObjectMgr->GetCreatureTemplate(auctioneerData->id1);
282 if (!auctioneerInfo)
283 {
284 LOG_ERROR("network.opcode", "Non existing auctioneer ({})", auctioneer.ToString());
285 return;
286 }
287
288 const AuctionHouseEntry* AHEntry = sAuctionMgr->GetAuctionHouseEntry(auctioneerInfo->faction);
289 AH->houseId = AHEntry->houseId;
290 }
291
292 // Required stack size of auction matches to current item stack size, just move item to auctionhouse
293 if (itemsCount == 1 && item->GetCount() == count[i])
294 {
295 AH->item_guid = item->GetGUID();
296 AH->item_template = item->GetEntry();
297 AH->itemCount = item->GetCount();
298 AH->owner = _player->GetGUID();
299 AH->startbid = bid;
301 AH->bid = 0;
302 AH->buyout = buyout;
303 AH->expire_time = GameTime::GetGameTime().count() + auctionTime;
304 AH->deposit = deposit;
305 AH->auctionHouseEntry = auctionHouseEntry;
306
307 LOG_DEBUG("network.opcode", "CMSG_AUCTION_SELL_ITEM: Player {} ({}) is selling item {} entry {} ({}) with count {} with initial bid {} with buyout {} and with time {} (in sec) in auctionhouse {}",
308 _player->GetName(), _player->GetGUID().ToString(), item->GetTemplate()->Name1, item->GetEntry(), item->GetGUID().ToString(), item->GetCount(), bid, buyout, auctionTime, AH->GetHouseId());
309 sAuctionMgr->AddAItem(item);
310 auctionHouse->AddAuction(AH);
311
312 _player->MoveItemFromInventory(item->GetBagSlot(), item->GetSlot(), true);
313
314 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
315 item->DeleteFromInventoryDB(trans);
316 item->SaveToDB(trans);
317 AH->SaveToDB(trans);
319 CharacterDatabase.CommitTransaction(trans);
320
322
324 return;
325 }
326 else // Required stack size of auction does not match to current item stack size, clone item and set correct stack size
327 {
328 Item* newItem = item->CloneItem(finalCount, _player);
329 if (!newItem)
330 {
331 LOG_ERROR("network.opcode", "CMSG_AUCTION_SELL_ITEM: Could not create clone of item {}", item->GetEntry());
333 return;
334 }
335
336 AH->item_guid = newItem->GetGUID();
337 AH->item_template = newItem->GetEntry();
338 AH->itemCount = newItem->GetCount();
339 AH->owner = _player->GetGUID();
340 AH->startbid = bid;
342 AH->bid = 0;
343 AH->buyout = buyout;
344 AH->expire_time = GameTime::GetGameTime().count() + auctionTime;
345 AH->deposit = deposit;
346 AH->auctionHouseEntry = auctionHouseEntry;
347
348 LOG_DEBUG("network.opcode", "CMSG_AUCTION_SELL_ITEM: Player {} ({}) is selling item {} entry {} ({}) with count {} with initial bid {} with buyout {} and with time {} (in sec) in auctionhouse {}",
349 _player->GetName(), _player->GetGUID().ToString(), newItem->GetTemplate()->Name1, newItem->GetEntry(), newItem->GetGUID().ToString(), newItem->GetCount(), bid, buyout, auctionTime, AH->GetHouseId());
350 sAuctionMgr->AddAItem(newItem);
351 auctionHouse->AddAuction(AH);
352
353 for (uint32 j = 0; j < itemsCount; ++j)
354 {
355 Item* item2 = items[j];
356
357 // Item stack count equals required count, ready to delete item - cloned item will be used for auction
358 if (item2->GetCount() == count[j])
359 {
360 _player->MoveItemFromInventory(item2->GetBagSlot(), item2->GetSlot(), true);
361
362 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
363 item2->DeleteFromInventoryDB(trans);
364 item2->DeleteFromDB(trans);
365 CharacterDatabase.CommitTransaction(trans);
366 delete item2;
367 }
368 else // Item stack count is bigger than required count, update item stack count and save to database - cloned item will be used for auction
369 {
370 item2->SetCount(item2->GetCount() - count[j]);
372 _player->ItemRemovedQuestCheck(item2->GetEntry(), count[j]);
374
375 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
376 item2->SaveToDB(trans);
377 CharacterDatabase.CommitTransaction(trans);
378 }
379 }
380
381 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
382 newItem->SaveToDB(trans);
383 AH->SaveToDB(trans);
385 CharacterDatabase.CommitTransaction(trans);
386
388
390 return;
391 }
392 }
393}
constexpr auto MINUTE
Definition: Common.h:56
#define MIN_AUCTION_TIME
@ AUCTIONHOUSE_NEUTRAL
@ AUCTION_SELL_ITEM
#define MAX_AUCTION_ITEMS
@ ERR_AUCTION_NOT_ENOUGHT_MONEY
@ ERR_AUCTION_ITEM_NOT_FOUND
@ ITEM_CHANGED
Definition: Item.h:204
@ ITEM_FLAG_CONJURED
Definition: ItemTemplate.h:149
@ ITEM_FIELD_DURATION
Definition: UpdateFields.h:40
@ CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION
Definition: IWorld.h:82
@ RATE_AUCTION_TIME
Definition: IWorld.h:490
@ ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION
Definition: DBCEnums.h:196
Seconds GetGameTime()
Definition: GameTime.cpp:38
uint8 GetHouseId() const
AuctionHouseEntry const * auctionHouseEntry
void SaveToDB(CharacterDatabaseTransaction trans) const
uint32 item_template
void AddAuction(AuctionEntry *auction)
static AuctionHouseEntry const * GetAuctionHouseEntry(uint32 factionTemplateId)
ObjectGuid::LowType GetSpawnId() const
Definition: Creature.h:66
static void DeleteFromInventoryDB(CharacterDatabaseTransaction trans, ObjectGuid::LowType itemGuid)
Definition: Item.cpp:534
void SetState(ItemUpdateState state, Player *forplayer=nullptr)
Definition: Item.cpp:716
virtual void SaveToDB(CharacterDatabaseTransaction trans)
Definition: Item.cpp:338
Item * CloneItem(uint32 count, Player const *player=nullptr) const
Definition: Item.cpp:1120
bool CanBeTraded(bool mail=false, bool trade=false) const
Definition: Item.cpp:796
void SetCount(uint32 value)
Definition: Item.h:264
bool IsNotEmptyBag() const
Definition: Item.cpp:313
uint32 GetMaxStackCount() const
Definition: Item.h:265
static void DeleteFromDB(CharacterDatabaseTransaction trans, ObjectGuid::LowType itemGuid)
Definition: Item.cpp:520
std::string Name1
Definition: ItemTemplate.h:633
uint32 GetUInt32Value(uint16 index) const
Definition: Object.cpp:305
uint32 GetEntry() const
Definition: Object.h:109
void SendUpdateToPlayer(Player *player)
Definition: Object.cpp:246
void ItemRemovedQuestCheck(uint32 entry, uint32 count)

◆ HandleAutoBankItemOpcode()

void WorldSession::HandleAutoBankItemOpcode ( WorldPackets::Bank::AutoBankItem packet)

Definition at line 67 of file BankHandler.cpp.

68{
69 LOG_DEBUG("network", "STORAGE: receive bag = {}, slot = {}", packet.Bag, packet.Slot);
70
71 if (!CanUseBank())
72 {
73 LOG_DEBUG("network", "WORLD: HandleAutoBankItemOpcode - Unit ({}) not found or you can't interact with him.", m_currentBankerGUID.ToString());
74 return;
75 }
76
77 Item* item = _player->GetItemByPos(packet.Bag, packet.Slot);
78 if (!item)
79 return;
80
81 ItemPosCountVec dest;
82 InventoryResult msg = _player->CanBankItem(NULL_BAG, NULL_SLOT, dest, item, false);
83 if (msg != EQUIP_ERR_OK)
84 {
85 _player->SendEquipError(msg, item, nullptr);
86 return;
87 }
88
89 if (dest.size() == 1 && dest[0].pos == item->GetPos())
90 {
91 _player->SendEquipError(EQUIP_ERR_NONE, item, nullptr);
92 return;
93 }
94
95 _player->RemoveItem(packet.Bag, packet.Slot, true);
97 _player->BankItem(dest, item, true);
99}
InventoryResult
Definition: Item.h:40
@ EQUIP_ERR_NONE
Definition: Item.h:100
std::vector< ItemPosCount > ItemPosCountVec
Definition: Player.h:772
@ NULL_BAG
Definition: Unit.h:210
@ NULL_SLOT
Definition: Unit.h:211
uint16 GetPos() const
Definition: Item.h:276
Item * BankItem(ItemPosCountVec const &dest, Item *pItem, bool update)
Definition: Player.h:1301
Item * GetItemByPos(uint16 pos) const
void RemoveItem(uint8 bag, uint8 slot, bool update, bool swap=false)
InventoryResult CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap, bool not_loading=true) const
void UpdateTitansGrip()
bool CanUseBank(ObjectGuid bankerGUID=ObjectGuid::Empty) const
Definition: BankHandler.cpp:27

◆ HandleAutoEquipItemOpcode()

void WorldSession::HandleAutoEquipItemOpcode ( WorldPacket recvPacket)

Definition at line 165 of file ItemHandler.cpp.

166{
167 //LOG_DEBUG("network.opcode", "WORLD: CMSG_AUTOEQUIP_ITEM");
168 uint8 srcbag, srcslot;
169
170 recvData >> srcbag >> srcslot;
171
172 Item* pSrcItem = _player->GetItemByPos(srcbag, srcslot);
173 if (!pSrcItem)
174 return; // only at cheat
175
176 ItemTemplate const* pProto = pSrcItem->GetTemplate();
177 if (!pProto)
178 {
180 return;
181 }
182
183 uint8 eslot = _player->FindEquipSlot(pProto, NULL_SLOT, !pSrcItem->IsBag());
184 if (eslot == NULL_SLOT)
185 {
187 return;
188 }
189
190 uint16 src = pSrcItem->GetPos();
191 uint16 dest = ((INVENTORY_SLOT_BAG_0 << 8) | eslot);
192 if (dest == src) // prevent equip in same slot, only at cheat
193 {
195 return;
196 }
197
198 Item* pDstItem = _player->GetItemByPos(dest);
199
200 // Remove item enchantments for now and restore it later
201 // Needed for swap sanity checks
202 if (pDstItem)
203 {
204 _player->ApplyEnchantment(pDstItem, false);
205 }
206
207 InventoryResult msg = _player->CanEquipItem(NULL_SLOT, dest, pSrcItem, !pSrcItem->IsBag());
208 if (msg != EQUIP_ERR_OK)
209 {
210 // Restore enchantments
211 if (pDstItem)
212 {
213 _player->ApplyEnchantment(pDstItem, true);
214 }
215
216 _player->SendEquipError(msg, pSrcItem, nullptr);
217 return;
218 }
219
220 if (!pDstItem) // empty slot, simple case
221 {
222 _player->RemoveItem(srcbag, srcslot, true);
223 _player->EquipItem(dest, pSrcItem, true);
225 }
226 else // have currently equipped item, not simple case
227 {
228 // Restore enchantments
229 _player->ApplyEnchantment(pDstItem, true);
230
231 uint8 dstbag = pDstItem->GetBagSlot();
232 uint8 dstslot = pDstItem->GetSlot();
233
234 msg = _player->CanUnequipItem(dest, !pSrcItem->IsBag());
235 if (msg != EQUIP_ERR_OK)
236 {
237 _player->SendEquipError(msg, pDstItem, nullptr);
238 return;
239 }
240
241 // check dest->src move possibility
242 ItemPosCountVec sSrc;
243 uint16 eSrc = 0;
244 if (_player->IsInventoryPos(src))
245 {
246 msg = _player->CanStoreItem(srcbag, srcslot, sSrc, pDstItem, true);
247 if (msg != EQUIP_ERR_OK)
248 msg = _player->CanStoreItem(srcbag, NULL_SLOT, sSrc, pDstItem, true);
249 if (msg != EQUIP_ERR_OK)
250 msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, sSrc, pDstItem, true);
251 }
252 else if (_player->IsBankPos(src))
253 {
254 msg = _player->CanBankItem(srcbag, srcslot, sSrc, pDstItem, true);
255 if (msg != EQUIP_ERR_OK)
256 msg = _player->CanBankItem(srcbag, NULL_SLOT, sSrc, pDstItem, true);
257 if (msg != EQUIP_ERR_OK)
258 msg = _player->CanBankItem(NULL_BAG, NULL_SLOT, sSrc, pDstItem, true);
259 }
260 else if (_player->IsEquipmentPos(src))
261 {
262 msg = _player->CanEquipItem(srcslot, eSrc, pDstItem, true);
263 if (msg == EQUIP_ERR_OK)
264 msg = _player->CanUnequipItem(eSrc, true);
265 }
266
267 if (msg != EQUIP_ERR_OK)
268 {
269 _player->SendEquipError(msg, pDstItem, pSrcItem);
270 return;
271 }
272
273 // now do moves, remove...
274 _player->RemoveItem(dstbag, dstslot, true, true);
275 _player->RemoveItem(srcbag, srcslot, true, true);
276
277 // add to dest
278 _player->EquipItem(dest, pSrcItem, true);
279
280 // add to src
281 if (_player->IsInventoryPos(src))
282 _player->StoreItem(sSrc, pDstItem, true);
283 else if (_player->IsBankPos(src))
284 _player->BankItem(sSrc, pDstItem, true);
285 else if (_player->IsEquipmentPos(src))
286 _player->EquipItem(eSrc, pDstItem, true);
287
289
290 // Xinef: Call this here after all needed items are equipped
292 }
293}
@ EQUIP_ERR_ITEM_CANT_BE_EQUIPPED
Definition: Item.h:61
@ EQUIP_ERR_ITEM_NOT_FOUND
Definition: Item.h:64
@ EQUIP_ERR_ITEMS_CANT_BE_SWAPPED
Definition: Item.h:62
#define INVENTORY_SLOT_BAG_0
Definition: Player.h:671
bool IsBag() const
Definition: Item.h:248
static bool IsEquipmentPos(uint16 pos)
Definition: Player.h:1232
InventoryResult CanUnequipItem(uint16 src, bool swap) const
void RemoveItemDependentAurasAndCasts(Item *pItem)
Definition: Player.cpp:12289
InventoryResult CanEquipItem(uint8 slot, uint16 &dest, Item *pItem, bool swap, bool not_loading=true) const
InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap=false) const
Definition: Player.h:1252
void ApplyEnchantment(Item *item, EnchantmentSlot slot, bool apply, bool apply_dur=true, bool ignore_condition=false)
Item * StoreItem(ItemPosCountVec const &pos, Item *pItem, bool update)
static bool IsInventoryPos(uint16 pos)
Definition: Player.h:1230
uint8 FindEquipSlot(ItemTemplate const *proto, uint32 slot, bool swap) const
void AutoUnequipOffhandIfNeed(bool force=false)
Definition: Player.cpp:12180
Item * EquipItem(uint16 pos, Item *pItem, bool update)
static bool IsBankPos(uint16 pos)
Definition: Player.h:1235

◆ HandleAutoEquipItemSlotOpcode()

void WorldSession::HandleAutoEquipItemSlotOpcode ( WorldPacket recvPacket)

Definition at line 105 of file ItemHandler.cpp.

106{
107 ObjectGuid itemguid;
108 uint8 dstslot;
109 recvData >> itemguid >> dstslot;
110
111 // cheating attempt, client should never send opcode in that case
113 return;
114
115 Item* item = _player->GetItemByGuid(itemguid);
116 uint16 dstpos = dstslot | (INVENTORY_SLOT_BAG_0 << 8);
117
118 if (!item || item->GetPos() == dstpos)
119 return;
120
121 _player->SwapItem(item->GetPos(), dstpos);
122}
void SwapItem(uint16 src, uint16 dst)

◆ HandleAutoStoreBagItemOpcode()

void WorldSession::HandleAutoStoreBagItemOpcode ( WorldPacket recvPacket)

Definition at line 1101 of file ItemHandler.cpp.

1102{
1103 //LOG_DEBUG("network.opcode", "WORLD: CMSG_AUTOSTORE_BAG_ITEM");
1104 uint8 srcbag, srcslot, dstbag;
1105
1106 recvData >> srcbag >> srcslot >> dstbag;
1107
1108 Item* pItem = _player->GetItemByPos(srcbag, srcslot);
1109 if (!pItem)
1110 return;
1111
1112 if (!_player->IsValidPos(dstbag, NULL_SLOT, false)) // can be autostore pos
1113 {
1115 return;
1116 }
1117
1118 uint16 src = pItem->GetPos();
1119
1120 // check unequip potability for equipped items and bank bags
1121 if (_player->IsEquipmentPos (src) || _player->IsBagPos (src))
1122 {
1124 if (msg != EQUIP_ERR_OK)
1125 {
1126 _player->SendEquipError(msg, pItem, nullptr);
1127 return;
1128 }
1129 }
1130
1131 ItemPosCountVec dest;
1132 InventoryResult msg = _player->CanStoreItem(dstbag, NULL_SLOT, dest, pItem, false);
1133 if (msg != EQUIP_ERR_OK)
1134 {
1135 _player->SendEquipError(msg, pItem, nullptr);
1136 return;
1137 }
1138
1139 // no-op: placed in same slot
1140 if (dest.size() == 1 && dest[0].pos == src)
1141 {
1142 // just remove grey item state
1143 _player->SendEquipError(EQUIP_ERR_NONE, pItem, nullptr);
1144 return;
1145 }
1146
1147 _player->RemoveItem(srcbag, srcslot, true);
1148 _player->StoreItem(dest, pItem, true);
1150}
@ EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT
Definition: Item.h:44
static bool IsBagPos(uint16 pos)
bool IsValidPos(uint16 pos, bool explicit_pos)
Definition: Player.h:1237

◆ HandleAutoStoreBankItemOpcode()

void WorldSession::HandleAutoStoreBankItemOpcode ( WorldPackets::Bank::AutoStoreBankItem packet)

Definition at line 101 of file BankHandler.cpp.

102{
103 LOG_DEBUG("network", "STORAGE: receive bag = {}, slot = {}", packet.Bag, packet.Slot);
104
105 if (!CanUseBank())
106 {
107 LOG_DEBUG("network", "WORLD: HandleAutoStoreBankItemOpcode - Unit ({}) not found or you can't interact with him.", m_currentBankerGUID.ToString());
108 return;
109 }
110
111 Item* item = _player->GetItemByPos(packet.Bag, packet.Slot);
112 if (!item)
113 return;
114
115 if (_player->IsBankPos(packet.Bag, packet.Slot)) // moving from bank to inventory
116 {
117 ItemPosCountVec dest;
118 InventoryResult msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, dest, item, false);
119 if (msg != EQUIP_ERR_OK)
120 {
121 _player->SendEquipError(msg, item, nullptr);
122 return;
123 }
124
125 _player->RemoveItem(packet.Bag, packet.Slot, true);
126 if (Item const* storedItem = _player->StoreItem(dest, item, true))
127 _player->ItemAddedQuestCheck(storedItem->GetEntry(), storedItem->GetCount());
128 }
129 else // moving from inventory to bank
130 {
131 ItemPosCountVec dest;
132 InventoryResult msg = _player->CanBankItem(NULL_BAG, NULL_SLOT, dest, item, false);
133 if (msg != EQUIP_ERR_OK)
134 {
135 _player->SendEquipError(msg, item, nullptr);
136 return;
137 }
138
139 _player->RemoveItem(packet.Bag, packet.Slot, true);
141 _player->BankItem(dest, item, true);
143 }
144}
void ItemAddedQuestCheck(uint32 entry, uint32 count)

◆ HandleAutostoreLootItemOpcode()

void WorldSession::HandleAutostoreLootItemOpcode ( WorldPacket recvPacket)

Definition at line 33 of file LootHandler.cpp.

34{
35 LOG_DEBUG("network", "WORLD: CMSG_AUTOSTORE_LOOT_ITEM");
36 Player* player = GetPlayer();
37 ObjectGuid lguid = player->GetLootGUID();
38 Loot* loot = nullptr;
39 uint8 lootSlot = 0;
40
41 recvData >> lootSlot;
42
43 if (lguid.IsGameObject())
44 {
45 GameObject* go = player->GetMap()->GetGameObject(lguid);
46 // xinef: cheating protection
47 //if (player->GetGroup() && player->GetGroup()->GetLootMethod() == MASTER_LOOT && player->GetGUID() != player->GetGroup()->GetMasterLooterGuid())
48 // go = nullptr;
49
50 // not check distance for GO in case owned GO (fishing bobber case, for example) or Fishing hole GO
51 if (!go || ((go->GetOwnerGUID() != _player->GetGUID() && go->GetGoType() != GAMEOBJECT_TYPE_FISHINGHOLE) && !go->IsWithinDistInMap(_player)))
52 {
53 player->SendLootRelease(lguid);
54 return;
55 }
56
57 loot = &go->loot;
58 }
59 else if (lguid.IsItem())
60 {
61 Item* pItem = player->GetItemByGuid(lguid);
62
63 if (!pItem)
64 {
65 player->SendLootRelease(lguid);
66 return;
67 }
68
69 loot = &pItem->loot;
70 }
71 else if (lguid.IsCorpse())
72 {
73 Corpse* bones = ObjectAccessor::GetCorpse(*player, lguid);
74 if (!bones)
75 {
76 player->SendLootRelease(lguid);
77 return;
78 }
79
80 loot = &bones->loot;
81 }
82 else
83 {
84 Creature* creature = GetPlayer()->GetMap()->GetCreature(lguid);
85
86 bool lootAllowed = creature && creature->IsAlive() == (player->getClass() == CLASS_ROGUE && creature->loot.loot_type == LOOT_PICKPOCKETING);
87 if (!lootAllowed || !creature->IsWithinDistInMap(_player, INTERACTION_DISTANCE))
88 {
89 player->SendLootError(lguid, lootAllowed ? LOOT_ERROR_TOO_FAR : LOOT_ERROR_DIDNT_KILL);
90 return;
91 }
92
93 loot = &creature->loot;
94 }
95
96 player->StoreLootItem(lootSlot, loot);
97
98 // If player is removing the last LootItem, delete the empty container.
99 if (loot->isLooted() && lguid.IsItem())
100 DoLootRelease(lguid);
101}
@ LOOT_ERROR_TOO_FAR
Definition: LootMgr.h:98
@ LOOT_ERROR_DIDNT_KILL
Definition: LootMgr.h:97
ObjectGuid GetLootGUID() const
Definition: Player.h:1942
void SendLootError(ObjectGuid guid, LootError error)
Definition: Player.cpp:8022
void StoreLootItem(uint8 lootSlot, Loot *loot)
Definition: Player.cpp:13220
void DoLootRelease(ObjectGuid lguid)

◆ HandleBankerActivateOpcode()

void WorldSession::HandleBankerActivateOpcode ( WorldPacket recvData)

Definition at line 45 of file BankHandler.cpp.

46{
47 ObjectGuid guid;
48
49 LOG_DEBUG("network", "WORLD: Received CMSG_BANKER_ACTIVATE");
50
51 recvData >> guid;
52
54 if (!unit)
55 {
56 LOG_DEBUG("network", "WORLD: HandleBankerActivateOpcode - Unit ({}) not found or you can not interact with him.", guid.ToString());
57 return;
58 }
59
60 // remove fake death
61 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
63
64 SendShowBank(guid);
65}
void SendShowBank(ObjectGuid guid)

◆ HandleBattlefieldLeaveOpcode()

void WorldSession::HandleBattlefieldLeaveOpcode ( WorldPacket recvData)

Definition at line 585 of file BattleGroundHandler.cpp.

586{
587 LOG_DEBUG("network", "WORLD: Recvd CMSG_LEAVE_BATTLEFIELD Message");
588
589 recvData.read_skip<uint8>(); // unk1
590 recvData.read_skip<uint8>(); // unk2
591 recvData.read_skip<uint32>(); // BattlegroundTypeId
592 recvData.read_skip<uint16>(); // unk3
593
594 // not allow leave battleground in combat
595 if (_player->IsInCombat())
597 if (bg->GetStatus() != STATUS_WAIT_LEAVE)
598 return;
599
601}
@ STATUS_WAIT_LEAVE
Definition: Battleground.h:198
void LeaveBattleground(Battleground *bg=nullptr)
Definition: Player.cpp:11061
bool IsInCombat() const
Definition: Unit.h:1685

◆ HandleBattlefieldListOpcode()

void WorldSession::HandleBattlefieldListOpcode ( WorldPacket recvData)

Definition at line 365 of file BattleGroundHandler.cpp.

366{
367 LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEFIELD_LIST Message");
368
369 uint32 bgTypeId;
370 recvData >> bgTypeId; // id from DBC
371
372 uint8 fromWhere;
373 recvData >> fromWhere; // 0 - battlemaster (lua: ShowBattlefieldList), 1 - UI (lua: RequestBattlegroundInstanceInfo)
374
375 uint8 canGainXP;
376 recvData >> canGainXP; // players with locked xp have their own bg queue on retail
377
378 BattlemasterListEntry const* bl = sBattlemasterListStore.LookupEntry(bgTypeId);
379 if (!bl)
380 {
381 LOG_DEBUG("bg.battleground", "BattlegroundHandler: invalid bgtype ({}) with player (Name: {}, {}) received.", bgTypeId, _player->GetName(), _player->GetGUID().ToString());
382 return;
383 }
384
385 WorldPacket data;
386 sBattlegroundMgr->BuildBattlegroundListPacket(&data, ObjectGuid::Empty, _player, BattlegroundTypeId(bgTypeId), fromWhere);
387 SendPacket(&data);
388}
DBCStorage< BattlemasterListEntry > sBattlemasterListStore(BattlemasterListEntryfmt)
BattlegroundTypeId

◆ HandleBattleFieldPortOpcode()

void WorldSession::HandleBattleFieldPortOpcode ( WorldPacket recvData)

Definition at line 390 of file BattleGroundHandler.cpp.

391{
392 uint8 arenaType; // arenatype if arena
393 uint8 unk2; // unk, can be 0x0 (may be if was invited?) and 0x1
394 uint32 bgTypeId_; // type id from dbc
395 uint16 unk; // 0x1F90 constant?
396 uint8 action; // enter battle 0x1, leave queue 0x0
397
398 recvData >> arenaType >> unk2 >> bgTypeId_ >> unk >> action;
399
400 // bgTypeId not valid
401 if (!sBattlemasterListStore.LookupEntry(bgTypeId_))
402 {
403 LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}. Invalid BgType!", GetPlayerInfo(), arenaType, unk2, bgTypeId_, action);
404 return;
405 }
406
407 // player not in any queue, so can't really answer
409 {
410 LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}. Player not in queue!", GetPlayerInfo(), arenaType, unk2, bgTypeId_, action);
411 return;
412 }
413
415 {
417 return;
418 }
419
420 // get BattlegroundQueue for received
421 BattlegroundTypeId bgTypeId = BattlegroundTypeId(bgTypeId_);
422 BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, arenaType);
423 BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
424
425 if (!sScriptMgr->CanBattleFieldPort(_player, arenaType, bgTypeId, action))
426 return;
427
428 // get group info from queue
429 GroupQueueInfo ginfo;
430 if (!bgQueue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo))
431 {
432 LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}. Player not in queue (No player Group Info)!",
433 GetPlayerInfo(), arenaType, unk2, bgTypeId_, action);
434 return;
435 }
436
437 // to accept, player must be invited to particular battleground id
438 if (!ginfo.IsInvitedToBGInstanceGUID && action == 1)
439 {
440 LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}. Player is not invited to any bg!",
441 GetPlayerInfo(), arenaType, unk2, bgTypeId_, action);
442 return;
443 }
444
445 Battleground* bg = sBattlegroundMgr->GetBattleground(ginfo.IsInvitedToBGInstanceGUID, bgTypeId);
446 if (!bg)
447 {
448 if (action)
449 {
450 LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}. Cant find BG with id {}!",
451 GetPlayerInfo(), arenaType, unk2, bgTypeId_, action, ginfo.IsInvitedToBGInstanceGUID);
452 return;
453 }
454
455 bg = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId);
456 if (!bg)
457 {
458 LOG_ERROR("network", "BattlegroundHandler: bg_template not found for type id {}.", bgTypeId);
459 return;
460 }
461 }
462
463 LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT {} ArenaType: {}, Unk: {}, BgType: {}, Action: {}.",
464 GetPlayerInfo(), arenaType, unk2, bgTypeId_, action);
465
466 // expected bracket entry
468 if (!bracketEntry)
469 return;
470
471 // safety checks
472 if (action == 1 && ginfo.ArenaType == 0)
473 {
474 // can't join with deserter, check it here right before joining to be sure
476 {
477 WorldPacket data;
478 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS);
479 SendPacket(&data);
480 action = 0;
481 LOG_DEBUG("bg.battleground", "Player {} {} has a deserter debuff, do not port him to battleground!", _player->GetName(), _player->GetGUID().ToString());
482 }
483
484 if (_player->getLevel() > bg->GetMaxLevel())
485 {
486 LOG_ERROR("network", "Player {} {} has level ({}) higher than maxlevel ({}) of battleground ({})! Do not port him to battleground!",
488 action = 0;
489 }
490 }
491
492 // get player queue slot index for this bg (can be in up to 2 queues at the same time)
493 uint32 queueSlot = _player->GetBattlegroundQueueIndex(bgQueueTypeId);
494 WorldPacket data;
495
496 if (action) // accept
497 {
498 // check Freeze debuff
499 if (_player->HasAura(9454))
500 return;
501
502 if (!_player->IsInvitedForBattlegroundQueueType(bgQueueTypeId))
503 return; // cheating?
504
505 // set entry point if not in battleground
506 if (!_player->InBattleground())
508
509 // resurrect the player
510 if (!_player->IsAlive())
511 {
514 }
515
516 TeamId teamId = ginfo.teamId;
517
518 // send status packet
519 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime(), bg->GetArenaType(), teamId);
520 SendPacket(&data);
521
522 // remove battleground queue status from BGmgr
523 bgQueue.RemovePlayer(_player->GetGUID(), false);
524
525 // this is still needed here if battleground "jumping" shouldn't add deserter debuff
526 // also this is required to prevent stuck at old battleground after SetBattlegroundId set to new
527 if (Battleground* currentBg = _player->GetBattleground())
528 currentBg->RemovePlayerAtLeave(_player);
529
530 for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
531 {
532 auto playerBgQueueTypeId = _player->GetBattlegroundQueueTypeId(i);
533 if (playerBgQueueTypeId != BATTLEGROUND_QUEUE_NONE && playerBgQueueTypeId != bgQueueTypeId)
534 {
535 _player->RemoveBattlegroundQueueId(playerBgQueueTypeId);
536 sBattlegroundMgr->GetBattlegroundQueue(playerBgQueueTypeId).RemovePlayer(_player->GetGUID(), true);
537 }
538 }
539
540 // Remove from LFG queues
541 sLFGMgr->LeaveAllLfgQueues(_player->GetGUID(), false);
542
543 _player->SetBattlegroundId(bg->GetInstanceID(), bg->GetBgTypeID(), queueSlot, true, bgTypeId == BATTLEGROUND_RB, teamId);
544 sBattlegroundMgr->SendToBattleground(_player, ginfo.IsInvitedToBGInstanceGUID, bgTypeId);
545
546 LOG_DEBUG("bg.battleground", "Battleground: player {} {} joined battle for bg {}, bgtype {}, queue type {}.", _player->GetName(), _player->GetGUID().ToString(), bg->GetInstanceID(), bg->GetBgTypeID(), bgQueueTypeId);
547 }
548 else // leave queue
549 {
550 for (auto const& playerGuid : ginfo.Players)
551 {
552 auto player = ObjectAccessor::FindConnectedPlayer(playerGuid);
553 if (!player)
554 continue;
555
556 bgQueue.RemovePlayer(playerGuid, true);
557 player->RemoveBattlegroundQueueId(bgQueueTypeId);
558
559 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0, TEAM_NEUTRAL);
560 player->SendDirectMessage(&data);
561
562 LOG_DEBUG("bg.battleground", "Battleground: player {} {} left queue for bgtype {}, queue type {}.", player->GetName(), playerGuid.ToString(), bg->GetBgTypeID(), bgQueueTypeId);
563 }
564
565 // player left queue, we should update it - do not update Arena Queue
566 if (!ginfo.ArenaType)
567 sBattlegroundMgr->ScheduleQueueUpdate(ginfo.ArenaMatchmakerRating, ginfo.ArenaType, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
568
569 // track if player refuses to join the BG after being invited
570 if (bg->isBattleground() && (bg->GetStatus() == STATUS_IN_PROGRESS || bg->GetStatus() == STATUS_WAIT_JOIN))
571 {
573 {
575 stmt->SetData(0, _player->GetGUID().GetCounter());
577 CharacterDatabase.Execute(stmt);
578 }
579
580 sScriptMgr->OnBattlegroundDesertion(_player, BG_DESERTION_TYPE_LEAVE_QUEUE);
581 }
582 }
583}
@ CHAR_INS_DESERTER_TRACK
@ BG_DESERTION_TYPE_LEAVE_QUEUE
Definition: Battleground.h:52
@ STATUS_NONE
Definition: Battleground.h:194
@ STATUS_WAIT_JOIN
Definition: Battleground.h:196
PvPDifficultyEntry const * GetBattlegroundBracketByLevel(uint32 mapid, uint32 level)
Definition: DBCStores.cpp:781
#define sLFGMgr
Definition: LFGMgr.h:638
@ LANG_YOU_IN_COMBAT
Definition: Language.h:55
@ CONFIG_BATTLEGROUND_TRACK_DESERTERS
Definition: IWorld.h:120
@ ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS
@ TEAM_NEUTRAL
@ BATTLEGROUND_RB
@ BATTLEGROUND_QUEUE_NONE
#define PLAYER_MAX_BATTLEGROUND_QUEUES
uint32 GetMapId() const
Definition: Battleground.h:420
uint8 GetArenaType() const
Definition: Battleground.h:335
uint32 GetInstanceID() const
Definition: Battleground.h:321
uint32 GetStartTime() const
Definition: Battleground.h:324
bool isBattleground() const
Definition: Battleground.h:389
BattlegroundStatus GetStatus() const
Definition: Battleground.h:322
uint32 GetMaxLevel() const
Definition: Battleground.h:329
BattlegroundTypeId GetBgTypeID(bool GetRandom=false) const
Definition: Battleground.h:319
uint32 ArenaMatchmakerRating
void RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount)
bool IsInvitedForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId) const
Definition: Player.cpp:11947
void SetEntryPoint()
Definition: Player.cpp:11024
bool InBattleground() const
Definition: Player.h:2200
bool InBattlegroundQueue(bool ignoreArena=false) const
Definition: Player.cpp:11922
void SetBattlegroundId(uint32 id, BattlegroundTypeId bgTypeId, uint32 queueSlot, bool invited, bool isRandom, TeamId teamId)
Definition: Player.cpp:12023
void RemoveBattlegroundQueueId(BattlegroundQueueTypeId val)
Definition: Player.cpp:11985
bool CanJoinToBattleground() const
Definition: Player.cpp:11098
uint32 GetBattlegroundQueueIndex(BattlegroundQueueTypeId bgQueueTypeId) const
Definition: Player.cpp:11938
BattlegroundQueueTypeId GetBattlegroundQueueTypeId(uint32 index) const
Definition: Player.cpp:11933
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition: Unit.cpp:5598
ObjectGuid GetCharmGUID() const
Definition: Unit.h:1819
BattlegroundBracketId GetBracketId() const

◆ HandleBattlefieldStatusOpcode()

void WorldSession::HandleBattlefieldStatusOpcode ( WorldPacket recvData)

Definition at line 603 of file BattleGroundHandler.cpp.

604{
605 // requested at login and on map change
606 // send status for current queues and current bg
607
608 WorldPacket data;
609
610 // for current bg send STATUS_IN_PROGRESS
612 if (bg->GetPlayers().count(_player->GetGUID()))
613 {
614 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, _player->GetCurrentBattlegroundQueueSlot(), STATUS_IN_PROGRESS, bg->GetEndTime(), bg->GetStartTime(), bg->GetArenaType(), _player->GetBgTeamId());
615 SendPacket(&data);
616 }
617
618 // for queued bgs send STATUS_WAIT_JOIN or STATUS_WAIT_QUEUE
619 for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
620 {
621 // check if in queue
623 if (!bgQueueTypeId)
624 continue;
625
626 // get group info from queue
627 BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
628 GroupQueueInfo ginfo;
629 if (!bgQueue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo))
630 continue;
631
632 BattlegroundTypeId bgTypeId = BattlegroundMgr::BGTemplateId(bgQueueTypeId);
633
634 // if invited - send STATUS_WAIT_JOIN
636 {
637 Battleground* bg = sBattlegroundMgr->GetBattleground(ginfo.IsInvitedToBGInstanceGUID, bgTypeId);
638 if (!bg)
639 continue;
640
641 uint32 remainingTime = (GameTime::GetGameTimeMS().count() < ginfo.RemoveInviteTime ? getMSTimeDiff(GameTime::GetGameTimeMS().count(), ginfo.RemoveInviteTime) : 1);
642 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, i, STATUS_WAIT_JOIN, remainingTime, 0, ginfo.ArenaType, TEAM_NEUTRAL, bg->isRated(), ginfo.BgTypeId);
643 SendPacket(&data);
644 }
645 // if not invited - send STATUS_WAIT_QUEUE
646 else
647 {
648 Battleground* bgt = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId);
649 if (!bgt)
650 continue;
651
652 // expected bracket entry
654 if (!bracketEntry)
655 continue;
656
657 uint32 avgWaitTime = bgQueue.GetAverageQueueWaitTime(&ginfo);
658 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bgt, i, STATUS_WAIT_QUEUE, avgWaitTime, getMSTimeDiff(ginfo.JoinTime, GameTime::GetGameTimeMS().count()), ginfo.ArenaType, TEAM_NEUTRAL, ginfo.IsRated);
659 SendPacket(&data);
660 }
661 }
662}
@ STATUS_WAIT_QUEUE
Definition: Battleground.h:195
bool isRated() const
Definition: Battleground.h:390
static BattlegroundTypeId BGTemplateId(BattlegroundQueueTypeId bgQueueTypeId)
BattlegroundTypeId BgTypeId
uint32 GetAverageQueueWaitTime(GroupQueueInfo *ginfo) const
uint32 GetCurrentBattlegroundQueueSlot() const
Definition: Player.h:2204
TeamId GetBgTeamId() const
Definition: Player.h:2226

◆ HandleBattlegroundPlayerPositionsOpcode()

void WorldSession::HandleBattlegroundPlayerPositionsOpcode ( WorldPacket recvData)

Definition at line 295 of file BattleGroundHandler.cpp.

296{
297 LOG_DEBUG("network", "WORLD: Recvd MSG_BATTLEGROUND_PLAYER_POSITIONS Message");
298
300 if (!bg) // can't be received if player not in battleground
301 return;
302
303 uint32 flagCarrierCount = 0;
304 Player* allianceFlagCarrier = nullptr;
305 Player* hordeFlagCarrier = nullptr;
306
308 {
309 allianceFlagCarrier = ObjectAccessor::FindPlayer(guid);
310 if (allianceFlagCarrier)
311 ++flagCarrierCount;
312 }
313
315 {
316 hordeFlagCarrier = ObjectAccessor::FindPlayer(guid);
317 if (hordeFlagCarrier)
318 ++flagCarrierCount;
319 }
320
321 WorldPacket data(MSG_BATTLEGROUND_PLAYER_POSITIONS, 4 + 4 + 16 * flagCarrierCount);
322 // Used to send several player positions (found used in AV)
323 data << 0; // CGBattlefieldInfo__m_numPlayerPositions
324 /*
325 for (CGBattlefieldInfo__m_numPlayerPositions)
326 data << guid << posx << posy;
327 */
328 data << flagCarrierCount;
329 if (allianceFlagCarrier)
330 {
331 data << allianceFlagCarrier->GetGUID();
332 data << float(allianceFlagCarrier->GetPositionX());
333 data << float(allianceFlagCarrier->GetPositionY());
334 }
335
336 if (hordeFlagCarrier)
337 {
338 data << hordeFlagCarrier->GetGUID();
339 data << float(hordeFlagCarrier->GetPositionX());
340 data << float(hordeFlagCarrier->GetPositionY());
341 }
342
343 SendPacket(&data);
344}
@ TEAM_HORDE
@ MSG_BATTLEGROUND_PLAYER_POSITIONS
Definition: Opcodes.h:775
Player * FindPlayer(ObjectGuid const guid)
virtual ObjectGuid GetFlagPickerGUID(TeamId=TEAM_NEUTRAL) const
Definition: Battleground.h:557

◆ HandleBattlemasterHelloOpcode()

void WorldSession::HandleBattlemasterHelloOpcode ( WorldPacket recvData)

Definition at line 34 of file BattleGroundHandler.cpp.

35{
36 ObjectGuid guid;
37 recvData >> guid;
38 LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEMASTER_HELLO Message from ({})", guid.ToString());
39
40 Creature* unit = GetPlayer()->GetMap()->GetCreature(guid);
41 if (!unit)
42 return;
43
44 if (!unit->IsBattleMaster()) // it's not battlemaster
45 return;
46
47 // Stop the npc if moving
49 unit->PauseMovement(pause);
50 unit->SetHomePosition(unit->GetPosition());
51
52 BattlegroundTypeId bgTypeId = sBattlegroundMgr->GetBattleMasterBG(unit->GetEntry());
53
54 if (!_player->GetBGAccessByLevel(bgTypeId))
55 {
56 // temp, must be gossip message...
58 return;
59 }
60
61 SendBattleGroundList(guid, bgTypeId);
62}
@ LANG_YOUR_BG_LEVEL_REQ_ERROR
Definition: Language.h:666
void SetHomePosition(float x, float y, float z, float o)
Definition: Creature.h:320
CreatureMovementData const & GetMovementTemplate() const
Definition: Creature.cpp:2856
uint32 GetInteractionPauseTimer() const
Definition: CreatureData.h:166
void GetPosition(float &x, float &y) const
Definition: Position.h:122
bool GetBGAccessByLevel(BattlegroundTypeId bgTypeId) const
Definition: Player.cpp:12035
bool IsBattleMaster() const
Definition: Unit.h:1654
virtual void PauseMovement(uint32 timer=0, uint8 slot=0)
Definition: Unit.cpp:16755
void SendBattleGroundList(ObjectGuid guid, BattlegroundTypeId bgTypeId=BATTLEGROUND_RB)

◆ HandleBattlemasterJoinArena()

void WorldSession::HandleBattlemasterJoinArena ( WorldPacket recvData)

Definition at line 664 of file BattleGroundHandler.cpp.

665{
666 LOG_DEBUG("network", "WORLD: CMSG_BATTLEMASTER_JOIN_ARENA");
667
668 ObjectGuid guid; // arena Battlemaster guid
669 uint8 arenaslot; // 2v2, 3v3 or 5v5
670 uint8 asGroup; // asGroup
671 uint8 isRated; // isRated
672
673 recvData >> guid >> arenaslot >> asGroup >> isRated;
674
675 // can't queue for rated without a group
676 if (isRated && !asGroup)
677 return;
678
679 // ignore if we already in BG or BG queue
680 if (_player->InBattleground())
681 return;
682
683 // find creature by guid
684 Creature* unit = GetPlayer()->GetMap()->GetCreature(guid);
685 if (!unit || !unit->IsBattleMaster())
686 return;
687
688 // get arena type
689 uint8 arenatype = 0;
690 uint32 ateamId = 0;
691 uint32 arenaRating = 0;
692 uint32 matchmakerRating = 0;
693 uint32 previousOpponents = 0;
694
695 switch (arenaslot)
696 {
697 case 0:
698 arenatype = ARENA_TYPE_2v2;
699 break;
700 case 1:
701 arenatype = ARENA_TYPE_3v3;
702 break;
703 case 2:
704 arenatype = ARENA_TYPE_5v5;
705 break;
706 default:
707 LOG_ERROR("network", "Unknown arena slot {} at HandleBattlemasterJoinArena()", arenaslot);
708 return;
709 }
710
711 // get template for all arenas
712 Battleground* bgt = sBattlegroundMgr->GetBattlegroundTemplate(BATTLEGROUND_AA);
713 if (!bgt)
714 {
715 LOG_ERROR("network", "Battleground: template bg (all arenas) not found");
716 return;
717 }
718
719 // arenas disabled
721 {
723 return;
724 }
725
726 BattlegroundTypeId bgTypeId = bgt->GetBgTypeID();
727
728 // expected bracket entry
730 if (!bracketEntry)
731 return;
732
733 // must have free queue slot
734 // pussywizard: allow being queued only in one arena queue, and it even cannot be together with bg queues
736 {
737 WorldPacket data;
738 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_BATTLEGROUND_CANNOT_QUEUE_FOR_RATED);
739 SendPacket(&data);
740 return;
741 }
742
743 // queue result (default ok)
745
746 if (!sScriptMgr->CanJoinInArenaQueue(_player, guid, arenaslot, bgTypeId, asGroup, isRated, err) && err <= 0)
747 {
748 WorldPacket data;
749 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
750 SendPacket(&data);
751 return;
752 }
753
754 BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, arenatype);
755 BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
756
757 // check if player can queue:
758 if (!asGroup)
759 {
760 lfg::LfgState lfgState = sLFGMgr->GetState(GetPlayer()->GetGUID());
761 if (GetPlayer()->InBattleground()) // currently in battleground
762 {
764 }
765 else if (lfgState > lfg::LFG_STATE_NONE && (lfgState != lfg::LFG_STATE_QUEUED || !sWorld->getBoolConfig(CONFIG_ALLOW_JOIN_BG_AND_LFG))) // using lfg system
766 {
768 }
769
770 if (err <= 0)
771 {
772 WorldPacket data;
773 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
774 SendPacket(&data);
775 return;
776 }
777
778 // check if already in queue
780 //player is already in this queue
781 return;
782
783 // check if has free queue slots
785 return;
786
787 GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, nullptr, bgTypeId, bracketEntry, arenatype, isRated != 0, false, arenaRating, matchmakerRating, ateamId, previousOpponents);
788 uint32 avgWaitTime = bgQueue.GetAverageQueueWaitTime(ginfo);
789 uint32 queueSlot = _player->AddBattlegroundQueueId(bgQueueTypeId);
790
791 WorldPacket data;
792 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bgt, queueSlot, STATUS_WAIT_QUEUE, avgWaitTime, 0, arenatype, TEAM_NEUTRAL);
793 SendPacket(&data);
794
795 LOG_DEBUG("bg.battleground", "Battleground: player joined queue for arena, skirmish, bg queue type {} bg type {}: {}, NAME {}", bgQueueTypeId, bgTypeId, _player->GetGUID().ToString(), _player->GetName());
796
797 sScriptMgr->OnPlayerJoinArena(_player);
798 }
799 // check if group can queue:
800 else
801 {
802 Group* grp = _player->GetGroup();
803 // no group or not a leader
804 if (!grp || grp->GetLeaderGUID() != _player->GetGUID())
805 return;
806
807 // additional checks for rated arenas
808 if (isRated)
809 {
810 // pussywizard: for rated matches check if season is in progress!
811 if (!sWorld->getBoolConfig(CONFIG_ARENA_SEASON_IN_PROGRESS))
812 return;
813
814 ateamId = _player->GetArenaTeamId(arenaslot);
815
816 // check team existence
817 ArenaTeam* at = sArenaTeamMgr->GetArenaTeamById(ateamId);
818 if (!at)
819 {
820 SendNotInArenaTeamPacket(arenatype);
821 return;
822 }
823
824 // get team rating for queueing
825 arenaRating = at->GetRating();
826 matchmakerRating = at->GetAverageMMR(grp);
827 if (arenaRating <= 0)
828 arenaRating = 1;
829
830 previousOpponents = at->GetPreviousOpponents();
831 }
832
833 err = grp->CanJoinBattlegroundQueue(bgt, bgQueueTypeId, arenatype, arenatype, (bool)isRated, arenaslot);
834
835 // Check queue group members
836 if (err)
837 {
838 grp->DoForAllMembers([&bgQueue, &err](Player* member)
839 {
840 if (bgQueue.IsPlayerInvitedToRatedArena(member->GetGUID()))
841 {
842 err = ERR_BATTLEGROUND_JOIN_FAILED;
843 }
844 });
845 }
846
847 uint32 avgWaitTime = 0;
848 if (err > 0)
849 {
850 LOG_DEBUG("bg.battleground", "Battleground: arena join as group start");
851
852 if (isRated)
853 {
854 LOG_DEBUG("bg.battleground", "Battleground: arena team id {}, leader {} queued with matchmaker rating {} for type {}", _player->GetArenaTeamId(arenaslot), _player->GetName(), matchmakerRating, arenatype);
855 bgt->SetRated(true);
856 }
857 else
858 {
859 bgt->SetRated(false);
860 }
861
862 GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, arenatype, isRated != 0, false, arenaRating, matchmakerRating, ateamId, previousOpponents);
863 avgWaitTime = bgQueue.GetAverageQueueWaitTime(ginfo);
864 }
865
866 WorldPacket data;
867 for (GroupReference* itr = grp->GetFirstMember(); itr != nullptr; itr = itr->next())
868 {
869 Player* member = itr->GetSource();
870 if (!member)
871 continue;
872
873 if (err <= 0)
874 {
875 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
876 member->GetSession()->SendPacket(&data);
877 continue;
878 }
879
880 uint32 queueSlot = member->AddBattlegroundQueueId(bgQueueTypeId);
881
882 // send status packet
883 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bgt, queueSlot, STATUS_WAIT_QUEUE, avgWaitTime, 0, arenatype, TEAM_NEUTRAL, isRated);
884 member->GetSession()->SendPacket(&data);
885
886 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
887 member->GetSession()->SendPacket(&data);
888
889 LOG_DEBUG("bg.battleground", "Battleground: player joined queue for arena as group bg queue type {} bg type {}: {}, NAME {}", bgQueueTypeId, bgTypeId, member->GetGUID().ToString(), member->GetName());
890
891 sScriptMgr->OnPlayerJoinArena(member);
892 }
893 }
894
895 sBattlegroundMgr->ScheduleQueueUpdate(matchmakerRating, arenatype, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
896}
@ ARENA_TYPE_5v5
Definition: Battleground.h:214
@ ARENA_TYPE_3v3
Definition: Battleground.h:213
@ ARENA_TYPE_2v2
Definition: Battleground.h:212
@ DISABLE_TYPE_BATTLEGROUND
Definition: DisableMgr.h:32
@ LANG_ARENA_DISABLED
Definition: Language.h:699
@ CONFIG_ARENA_SEASON_IN_PROGRESS
Definition: IWorld.h:123
@ CONFIG_ALLOW_JOIN_BG_AND_LFG
Definition: IWorld.h:174
GroupJoinBattlegroundResult
@ ERR_BATTLEGROUND_CANNOT_QUEUE_FOR_RATED
@ ERR_LFG_CANT_USE_BATTLEGROUND
@ ERR_BATTLEGROUND_NOT_IN_BATTLEGROUND
bool IsDisabledFor(DisableType type, uint32 entry, Unit const *unit, uint8 flags)
Definition: DisableMgr.cpp:304
LfgState
Definition: LFG.h:70
@ LFG_STATE_NONE
Definition: LFG.h:71
@ LFG_STATE_QUEUED
Definition: LFG.h:73
uint32 GetPreviousOpponents()
Definition: ArenaTeam.h:213
uint32 GetRating() const
Definition: ArenaTeam.h:159
uint32 GetAverageMMR(Group *group) const
Definition: ArenaTeam.cpp:682
void SetRated(bool state)
Definition: Battleground.h:354
bool IsPlayerInvitedToRatedArena(ObjectGuid pl_guid)
GroupQueueInfo * AddGroup(Player *leader, Group *group, BattlegroundTypeId bgTypeId, PvPDifficultyEntry const *bracketEntry, uint8 arenaType, bool isRated, bool isPremade, uint32 arenaRating, uint32 matchmakerRating, uint32 arenaTeamId=0, uint32 opponentsArenaTeamId=0)
bool HasFreeBattlegroundQueueId() const
Definition: Player.cpp:11976
uint32 AddBattlegroundQueueId(BattlegroundQueueTypeId val)
Definition: Player.cpp:11961
GroupJoinBattlegroundResult CanJoinBattlegroundQueue(Battleground const *bgTemplate, BattlegroundQueueTypeId bgQueueTypeId, uint32 MinPlayerCount, uint32 MaxPlayerCount, bool isRated, uint32 arenaSlot)
Definition: Group.cpp:1899
GroupReference * GetFirstMember()
Definition: Group.h:241
void DoForAllMembers(std::function< void(Player *)> const &worker)
Definition: Group.cpp:2478
ObjectGuid GetLeaderGUID() const
Definition: Group.cpp:2231
GroupReference * next()
void SendNotInArenaTeamPacket(uint8 type)

◆ HandleBattlemasterJoinOpcode()

void WorldSession::HandleBattlemasterJoinOpcode ( WorldPacket recvData)

Definition at line 71 of file BattleGroundHandler.cpp.

72{
73 ObjectGuid guid;
74 uint32 bgTypeId_;
75 uint32 instanceId;
76 uint8 joinAsGroup;
77 bool isPremade = false;
78
79 recvData >> guid; // battlemaster guid
80 recvData >> bgTypeId_; // battleground type id (DBC id)
81 recvData >> instanceId; // instance id, 0 if First Available selected
82 recvData >> joinAsGroup; // join as group
83
84 // entry not found
85 if (!sBattlemasterListStore.LookupEntry(bgTypeId_))
86 {
87 LOG_ERROR("network", "Battleground: invalid bgtype ({}) received. possible cheater? player {}", bgTypeId_, _player->GetGUID().ToString());
88 return;
89 }
90
91 // chosen battleground type is disabled
93 {
95 return;
96 }
97
98 LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from {}", guid.ToString());
99
100 // get queue typeid and random typeid to check if already queued for them
101 BattlegroundTypeId bgTypeId = BattlegroundTypeId(bgTypeId_);
102 BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, 0);
104
105 // safety check - bgQueueTypeId == BATTLEGROUND_QUEUE_NONE if tried to queue for arena using this function
106 if (bgQueueTypeId == BATTLEGROUND_QUEUE_NONE)
107 return;
108
109 // ignore if player is already in BG
110 if (_player->InBattleground())
111 return;
112
113 // get bg instance or bg template if instance not found
114 Battleground* bg = nullptr;
115 if (instanceId)
116 bg = sBattlegroundMgr->GetBattlegroundThroughClientInstance(instanceId, bgTypeId);
117
118 if (!bg)
119 bg = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId);
120
121 if (!bg)
122 return;
123
124 // expected bracket entry
126 if (!bracketEntry)
127 return;
128
129 // must have free queue slot
131 {
132 WorldPacket data;
133 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_BATTLEGROUND_TOO_MANY_QUEUES);
134 SendPacket(&data);
135 return;
136 }
137
138 // queue result (default ok)
140
141 if (!sScriptMgr->CanJoinInBattlegroundQueue(_player, guid, bgTypeId, joinAsGroup, err) && err <= 0)
142 {
143 WorldPacket data;
144 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
145 SendPacket(&data);
146 return;
147 }
148
149 BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
150
151 // check if player can queue:
152 if (!joinAsGroup)
153 {
154 lfg::LfgState lfgState = sLFGMgr->GetState(GetPlayer()->GetGUID());
155 if (GetPlayer()->InBattleground()) // currently in battleground
156 {
158 }
159 else if (lfgState > lfg::LFG_STATE_NONE && (lfgState != lfg::LFG_STATE_QUEUED || !sWorld->getBoolConfig(CONFIG_ALLOW_JOIN_BG_AND_LFG))) // using lfg system
160 {
162 }
163 else if (!_player->CanJoinToBattleground()) // has deserter debuff
164 {
166 }
167 else if (_player->InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeIdRandom)) // queued for random bg, so can't queue for anything else
168 {
169 err = ERR_IN_RANDOM_BG;
170 }
171 else if (_player->InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeId)) // queued for this bg
172 {
174 }
175 else if (_player->InBattlegroundQueue() && bgTypeId == BATTLEGROUND_RB) // already in queue, so can't queue for random
176 {
178 }
181 _player->InBattlegroundQueueForBattlegroundQueueType(BATTLEGROUND_QUEUE_5v5)) // can't be already queued for arenas
182 {
184 }
185 // don't let Death Knights join BG queues when they are not allowed to be teleported yet
186 else if (_player->getClass() == CLASS_DEATH_KNIGHT && _player->GetMapId() == 609 && !_player->IsGameMaster() && !_player->HasSpell(50977))
187 {
189 }
190 else if (!_player->GetBGAccessByLevel(bgTypeId))
191 {
193 }
194
195 if (err <= 0)
196 {
197 WorldPacket data;
198 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
199 SendPacket(&data);
200 return;
201 }
202
203 GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, nullptr, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0);
204 uint32 avgWaitTime = bgQueue.GetAverageQueueWaitTime(ginfo);
205 uint32 queueSlot = _player->AddBattlegroundQueueId(bgQueueTypeId);
206
207 // send status packet
208 WorldPacket data;
209 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgWaitTime, 0, 0, TEAM_NEUTRAL);
210 SendPacket(&data);
211
212 sScriptMgr->OnPlayerJoinBG(_player);
213 }
214 // check if group can queue:
215 else
216 {
217 Group* grp = _player->GetGroup();
218
219 // no group or not a leader
220 if (!grp || grp->GetLeaderGUID() != _player->GetGUID())
221 return;
222
223 grp->DoForAllMembers([&err, bgQueueTypeId, bgQueueTypeIdRandom, bgTypeId](Player* member)
224 {
225 if (member->InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeIdRandom)) // queued for random bg, so can't queue for anything else
226 {
227 err = ERR_IN_RANDOM_BG;
228 }
229 else if (member->InBattlegroundQueue() && bgTypeId == BATTLEGROUND_RB) // already in queue, so can't queue for random
230 {
231 err = ERR_IN_NON_RANDOM_BG;
232 }
235 member->InBattlegroundQueueForBattlegroundQueueType(BATTLEGROUND_QUEUE_5v5)) // can't be already queued for arenas
236 {
237 err = ERR_BATTLEGROUND_QUEUED_FOR_RATED;
238 }
239 else if (member->InBattlegroundQueueForBattlegroundQueueType(bgQueueTypeId)) // queued for this bg
240 {
241 err = ERR_BATTLEGROUND_NONE;
242 }
243 else if (!member->GetBGAccessByLevel(bgTypeId))
244 {
245 err = ERR_BATTLEGROUND_JOIN_TIMED_OUT;
246 }
247
248 if (err < 0)
249 {
250 return;
251 }
252 });
253
254 if (err)
255 {
256 err = grp->CanJoinBattlegroundQueue(bg, bgQueueTypeId, 0, bg->GetMaxPlayersPerTeam(), false, 0);
257 }
258
259 if (err <= 0)
260 {
261 grp->DoForAllMembers([err](Player* member)
262 {
263 WorldPacket data;
264 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
265 member->GetSession()->SendPacket(&data);
266 });
267
268 return;
269 }
270
271 isPremade = (grp->GetMembersCount() >= bg->GetMinPlayersPerTeam() && bgTypeId != BATTLEGROUND_RB);
272 uint32 avgWaitTime = 0;
273
274 GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0);
275 avgWaitTime = bgQueue.GetAverageQueueWaitTime(ginfo);
276
277 grp->DoForAllMembers([bg, err, bgQueueTypeId, avgWaitTime](Player* member)
278 {
279 WorldPacket data;
280
281 // send status packet
282 sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, member->AddBattlegroundQueueId(bgQueueTypeId), STATUS_WAIT_QUEUE, avgWaitTime, 0, 0, TEAM_NEUTRAL);
283 member->GetSession()->SendPacket(&data);
284
285 sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
286 member->GetSession()->SendPacket(&data);
287
288 sScriptMgr->OnPlayerJoinBG(member);
289 });
290 }
291
292 sBattlegroundMgr->ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
293}
@ LANG_BG_DISABLED
Definition: Language.h:698
@ ERR_IN_NON_RANDOM_BG
@ ERR_BATTLEGROUND_NONE
@ ERR_BATTLEGROUND_TOO_MANY_QUEUES
@ ERR_IN_RANDOM_BG
@ ERR_BATTLEGROUND_QUEUED_FOR_RATED
@ CLASS_DEATH_KNIGHT
@ BATTLEGROUND_QUEUE_2v2
@ BATTLEGROUND_QUEUE_5v5
@ BATTLEGROUND_QUEUE_3v3
uint32 GetMinPlayersPerTeam() const
Definition: Battleground.h:332
uint32 GetMaxPlayersPerTeam() const
Definition: Battleground.h:331
bool InBattlegroundQueueForBattlegroundQueueType(BattlegroundQueueTypeId bgQueueTypeId) const
Definition: Player.cpp:11956
bool IsGameMaster() const
Definition: Player.h:1136
bool HasSpell(uint32 spell) const override
Definition: Player.cpp:3810
uint32 GetMembersCount() const
Definition: Group.h:243

◆ HandleBeginTradeOpcode()

void WorldSession::HandleBeginTradeOpcode ( WorldPacket recvPacket)

Definition at line 518 of file TradeHandler.cpp.

519{
520 TradeData* my_trade = _player->m_trade;
521 if (!my_trade)
522 return;
523
526}
@ TRADE_STATUS_OPEN_WINDOW

◆ HandleBfEntryInviteResponse()

void WorldSession::HandleBfEntryInviteResponse ( WorldPacket recvData)

Definition at line 114 of file BattlefieldHandler.cpp.

115{
116 uint32 BattleId;
117 uint8 Accepted;
118
119 recvData >> BattleId >> Accepted;
120
121 Battlefield* Bf = sBattlefieldMgr->GetBattlefieldByBattleId(BattleId);
122 if (!Bf)
123 return;
124
125 //If player accept invitation
126 if (Accepted)
127 {
129 }
130 else
131 {
132 if (_player->GetZoneId() == Bf->GetZoneId())
134 }
135}
void KickPlayerFromBattlefield(ObjectGuid guid)
Kick player from battlefield and teleport him to kick-point location.
void PlayerAcceptInviteToWar(Player *player)
uint32 GetZoneId()
Definition: Battlefield.h:243

◆ HandleBfExitRequest()

void WorldSession::HandleBfExitRequest ( WorldPacket recvData)

Definition at line 137 of file BattlefieldHandler.cpp.

138{
139 uint32 BattleId;
140
141 recvData >> BattleId;
142
143 Battlefield* Bf = sBattlefieldMgr->GetBattlefieldByBattleId(BattleId);
144 if (!Bf)
145 return;
146
148}
void AskToLeaveQueue(Player *player)

◆ HandleBfQueueInviteResponse()

void WorldSession::HandleBfQueueInviteResponse ( WorldPacket recvData)

Definition at line 96 of file BattlefieldHandler.cpp.

97{
98 uint32 BattleId;
99 uint8 Accepted;
100
101 recvData >> BattleId >> Accepted;
102
103 Battlefield* Bf = sBattlefieldMgr->GetBattlefieldByBattleId(BattleId);
104 if (!Bf)
105 return;
106
107 if (Accepted)
108 {
110 }
111}
void PlayerAcceptInviteToQueue(Player *player)

◆ HandleBinderActivateOpcode()

void WorldSession::HandleBinderActivateOpcode ( WorldPacket recvPacket)

Definition at line 425 of file NPCHandler.cpp.

426{
427 ObjectGuid npcGUID;
428 recvData >> npcGUID;
429
430 if (!GetPlayer()->IsInWorld() || !GetPlayer()->IsAlive())
431 return;
432
434 if (!unit)
435 {
436 LOG_DEBUG("network", "WORLD: HandleBinderActivateOpcode - Unit ({}) not found or you can not interact with him.", npcGUID.ToString());
437 return;
438 }
439
440 // remove fake death
441 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
443
444 SendBindPoint(unit);
445}
@ UNIT_NPC_FLAG_INNKEEPER
Definition: Unit.h:532
void SendBindPoint(Creature *npc)
Definition: NPCHandler.cpp:447

◆ HandleBugOpcode()

void WorldSession::HandleBugOpcode ( WorldPacket recvPacket)

Definition at line 624 of file MiscHandler.cpp.

625{
626 uint32 suggestion, contentlen, typelen;
627 std::string content, type;
628
629 recv_data >> suggestion >> contentlen >> content;
630
631 recv_data >> typelen >> type;
632
633 if (suggestion == 0)
634 LOG_DEBUG("network", "WORLD: Received CMSG_BUG [Bug Report]");
635 else
636 LOG_DEBUG("network", "WORLD: Received CMSG_BUG [Suggestion]");
637
638 LOG_DEBUG("network", "{}", type);
639 LOG_DEBUG("network", "{}", content);
640
642
643 stmt->SetData(0, type);
644 stmt->SetData(1, content);
645
646 CharacterDatabase.Execute(stmt);
647}
@ CHAR_INS_BUG_REPORT

◆ HandleBusyTradeOpcode()

void WorldSession::HandleBusyTradeOpcode ( WorldPacket recvPacket)

Definition at line 76 of file TradeHandler.cpp.

77{
78 LOG_DEBUG("network", "WORLD: Busy Trade {}", _player->GetGUID().ToString());
79 // recvPacket.print_storage();
80}

◆ HandleBuybackItem()

void WorldSession::HandleBuybackItem ( WorldPacket recvPacket)

Definition at line 862 of file ItemHandler.cpp.

863{
864 LOG_DEBUG("network", "WORLD: Received CMSG_BUYBACK_ITEM");
865 ObjectGuid vendorguid;
866 uint32 slot;
867
868 recvData >> vendorguid >> slot;
869
871 if (!creature)
872 {
873 LOG_DEBUG("network", "WORLD: HandleBuybackItem - Unit ({}) not found or you can not interact with him.", vendorguid.ToString());
875 return;
876 }
877
878 // remove fake death
879 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
881
882 Item* pItem = _player->GetItemFromBuyBackSlot(slot);
883 if (pItem)
884 {
886 if (!_player->HasEnoughMoney(price))
887 {
889 return;
890 }
891
892 ItemPosCountVec dest;
893 InventoryResult msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, dest, pItem, false);
894 if (msg == EQUIP_ERR_OK)
895 {
896 if (sWorld->getBoolConfig(CONFIG_ITEMDELETE_VENDOR))
897 {
899 stmt->SetData(0, _player->GetGUID().GetCounter());
900 stmt->SetData(1, pItem->GetEntry());
901 stmt->SetData(2, pItem->GetCount());
902 CharacterDatabase.Execute(stmt);
903 }
904
905 _player->ModifyMoney(-(int32)price);
907 _player->ItemAddedQuestCheck(pItem->GetEntry(), pItem->GetCount());
908 _player->StoreItem(dest, pItem, true);
909 }
910 else
911 _player->SendEquipError(msg, pItem, nullptr);
912 return;
913 }
914 else
916}
@ CHAR_DEL_RECOVERY_ITEM
@ BUY_ERR_CANT_FIND_ITEM
Definition: Item.h:135
@ BUY_ERR_NOT_ENOUGHT_MONEY
Definition: Item.h:137
@ SELL_ERR_CANT_FIND_VENDOR
Definition: Item.h:151
@ PLAYER_FIELD_BUYBACK_PRICE_1
Definition: UpdateFields.h:372
@ BUYBACK_SLOT_START
Definition: Player.h:725
@ UNIT_NPC_FLAG_VENDOR
Definition: Unit.h:523
@ CONFIG_ITEMDELETE_VENDOR
Definition: IWorld.h:163
void RemoveItemFromBuyBackSlot(uint32 slot, bool del)
void SendSellError(SellResult msg, Creature *creature, ObjectGuid guid, uint32 param)
Item * GetItemFromBuyBackSlot(uint32 slot)
void SendBuyError(BuyResult msg, Creature *creature, uint32 item, uint32 param)

◆ HandleBuyBankSlotOpcode()

void WorldSession::HandleBuyBankSlotOpcode ( WorldPackets::Bank::BuyBankSlot buyBankSlot)

Definition at line 146 of file BankHandler.cpp.

147{
149 if (!CanUseBank(buyBankSlot.Banker))
150 {
152 SendPacket(packet.Write());
153 LOG_DEBUG("network", "WORLD: HandleBuyBankSlotOpcode - {} not found or you can't interact with him.", buyBankSlot.Banker.ToString());
154 return;
155 }
156
158
159 // next slot
160 ++slot;
161
162 LOG_INFO("network", "PLAYER: Buy bank bag slot, slot number = {}", slot);
163
164 BankBagSlotPricesEntry const* slotEntry = sBankBagSlotPricesStore.LookupEntry(slot);
165
166 if (!slotEntry)
167 {
169 SendPacket(packet.Write());
170 return;
171 }
172
173 uint32 price = slotEntry->price;
174
175 if (!_player->HasEnoughMoney(price))
176 {
178 SendPacket(packet.Write());
179 return;
180 }
181
183 _player->ModifyMoney(-int32(price));
184
185 packet.Result = ERR_BANKSLOT_OK;
186 SendPacket(packet.Write());
187
189}
#define LOG_INFO(filterType__,...)
Definition: Log.h:167
DBCStorage< BankBagSlotPricesEntry > sBankBagSlotPricesStore(BankBagSlotPricesEntryfmt)
@ ERR_BANKSLOT_NOTBANKER
Definition: Player.h:114
@ ERR_BANKSLOT_FAILED_TOO_MANY
Definition: Player.h:112
@ ERR_BANKSLOT_OK
Definition: Player.h:115
@ ERR_BANKSLOT_INSUFFICIENT_FUNDS
Definition: Player.h:113
@ ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT
Definition: DBCEnums.h:165
uint8 GetBankBagSlotCount() const
Definition: Player.h:1239
void SetBankBagSlotCount(uint8 count)
Definition: Player.h:1240
WorldPacket const * Write() override
Definition: BankPackets.cpp:37

◆ HandleBuyItemInSlotOpcode()

void WorldSession::HandleBuyItemInSlotOpcode ( WorldPacket recvPacket)

Definition at line 918 of file ItemHandler.cpp.

919{
920 LOG_DEBUG("network", "WORLD: Received CMSG_BUY_ITEM_IN_SLOT");
921 ObjectGuid vendorguid, bagguid;
922 uint32 item, slot, count;
923 uint8 bagslot;
924
925 recvData >> vendorguid >> item >> slot >> bagguid >> bagslot >> count;
926
927 // client expects count starting at 1, and we send vendorslot+1 to client already
928 if (slot > 0)
929 --slot;
930 else
931 return; // cheating
932
933 uint8 bag = NULL_BAG; // init for case invalid bagGUID
934
935 // find bag slot by bag guid
936 if (bagguid == _player->GetGUID())
938 else
939 {
941 {
942 if (Bag* pBag = _player->GetBagByPos(i))
943 {
944 if (bagguid == pBag->GetGUID())
945 {
946 bag = i;
947 break;
948 }
949 }
950 }
951 }
952
953 // bag not found, cheating?
954 if (bag == NULL_BAG)
955 return;
956
957 GetPlayer()->BuyItemFromVendorSlot(vendorguid, slot, item, count, bag, bagslot);
958}
@ INVENTORY_SLOT_BAG_START
Definition: Player.h:700
@ INVENTORY_SLOT_BAG_END
Definition: Player.h:701
Definition: Bag.h:28
Bag * GetBagByPos(uint8 slot) const
bool BuyItemFromVendorSlot(ObjectGuid vendorguid, uint32 vendorslot, uint32 item, uint8 count, uint8 bag, uint8 slot)
Definition: Player.cpp:10436

◆ HandleBuyItemOpcode()

void WorldSession::HandleBuyItemOpcode ( WorldPacket recvPacket)

Definition at line 960 of file ItemHandler.cpp.

961{
962 LOG_DEBUG("network", "WORLD: Received CMSG_BUY_ITEM");
963 ObjectGuid vendorguid;
964 uint32 item, slot, count;
965 uint8 unk1;
966
967 recvData >> vendorguid >> item >> slot >> count >> unk1;
968
969 // client expects count starting at 1, and we send vendorslot+1 to client already
970 if (slot > 0)
971 --slot;
972 else
973 return; // cheating
974
975 GetPlayer()->BuyItemFromVendorSlot(vendorguid, slot, item, count, NULL_BAG, NULL_SLOT);
976}

◆ HandleBuyStableSlot()

void WorldSession::HandleBuyStableSlot ( WorldPacket recvPacket)

Definition at line 739 of file NPCHandler.cpp.

740{
741 LOG_DEBUG("network", "WORLD: Recv CMSG_BUY_STABLE_SLOT.");
742 ObjectGuid npcGUID;
743
744 recvData >> npcGUID;
745
746 if (!CheckStableMaster(npcGUID))
747 {
749 return;
750 }
751
752 // remove fake death
753 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
755
756 PetStable& petStable = GetPlayer()->GetOrInitPetStable();
757 if (petStable.MaxStabledPets < MAX_PET_STABLES)
758 {
759 StableSlotPricesEntry const* SlotPrice = sStableSlotPricesStore.LookupEntry(petStable.MaxStabledPets + 1);
760 if (_player->HasEnoughMoney(SlotPrice->Price))
761 {
762 ++petStable.MaxStabledPets;
763 _player->ModifyMoney(-int32(SlotPrice->Price));
765 }
766 else
768 }
769 else
771}
DBCStorage< StableSlotPricesEntry > sStableSlotPricesStore(StableSlotPricesfmt)
constexpr auto MAX_PET_STABLES
Definition: PetDefines.h:36
@ STABLE_ERR_MONEY
Definition: NPCHandler.cpp:38
@ STABLE_SUCCESS_BUY_SLOT
Definition: NPCHandler.cpp:42
@ STABLE_ERR_STABLE
Definition: NPCHandler.cpp:39
uint32 MaxStabledPets
Definition: PetDefines.h:222
PetStable & GetOrInitPetStable()
Definition: Player.cpp:15272
bool CheckStableMaster(ObjectGuid guid)
Definition: PetHandler.cpp:657
void SendStableResult(uint8 guid)
Definition: NPCHandler.cpp:550

◆ HandleCalendarAddEvent()

void WorldSession::HandleCalendarAddEvent ( WorldPacket recvData)

Definition at line 239 of file CalendarHandler.cpp.

240{
241 ObjectGuid guid = _player->GetGUID();
242
243 std::string title;
244 std::string description;
245 uint8 type;
246 uint8 repeatable;
247 uint32 maxInvites;
248 int32 dungeonId;
249 uint32 eventPackedTime;
250 uint32 unkPackedTime;
251 uint32 flags;
252
253 recvData >> title >> description >> type >> repeatable >> maxInvites >> dungeonId;
254 recvData.ReadPackedTime(eventPackedTime);
255 recvData.ReadPackedTime(unkPackedTime);
256 recvData >> flags;
257
258 // prevent attacks with non-utf8 chars -> with multiple packets it will hang up the db due to errors.
259 if (!validUtf8String(recvData, title, "create", guid) || title.size() > 31 || !validUtf8String(recvData, description, "create", guid) || description.size() > 255)
260 return;
261
262 // prevent events in the past
263 // To Do: properly handle timezones and remove the "- time_t(86400L)" hack
264 if (time_t(eventPackedTime) < (GameTime::GetGameTime().count() - time_t(86400L)))
265 {
266 recvData.rfinish();
267 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_PASSED);
268 return;
269 }
270
271 // If the event is a guild event, check if the player is in a guild
273 {
274 if (!_player->GetGuildId())
275 {
276 recvData.rfinish();
277 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_GUILD_PLAYER_NOT_IN_GUILD);
278 return;
279 }
280 }
281
282 // Check if the player reached the max number of events allowed to create
284 {
285 if (sCalendarMgr->GetGuildEvents(_player->GetGuildId()).size() >= CALENDAR_MAX_GUILD_EVENTS)
286 {
287 recvData.rfinish();
288 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_GUILD_EVENTS_EXCEEDED);
289 return;
290 }
291 }
292 else
293 {
294 if (sCalendarMgr->GetEventsCreatedBy(guid).size() >= CALENDAR_MAX_EVENTS)
295 {
296 recvData.rfinish();
297 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENTS_EXCEEDED);
298 return;
299 }
300 }
301
303 {
304 recvData.rfinish();
305 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_INTERNAL);
306 return;
307 }
309
310 CalendarEvent* calendarEvent = new CalendarEvent(sCalendarMgr->GetFreeEventId(), guid, 0, CalendarEventType(type), dungeonId,
311 time_t(eventPackedTime), flags, time_t(unkPackedTime), title, description);
312
313 if (calendarEvent->IsGuildEvent() || calendarEvent->IsGuildAnnouncement())
314 if (Player* creator = ObjectAccessor::FindConnectedPlayer(guid))
315 calendarEvent->SetGuildId(creator->GetGuildId());
316
317 if (calendarEvent->IsGuildAnnouncement())
318 {
319 // 946684800 is 01/01/2000 00:00:00 - default response time
320 CalendarInvite* invite = new CalendarInvite(0, calendarEvent->GetEventId(), ObjectGuid::Empty, guid, 946684800, CALENDAR_STATUS_NOT_SIGNED_UP, CALENDAR_RANK_PLAYER, "");
321 sCalendarMgr->AddInvite(calendarEvent, invite);
322 }
323 else
324 {
325 uint32 inviteCount;
329
330 memset(status, 0, sizeof(status));
331 memset(rank, 0, sizeof(rank));
332
333 try
334 {
335 recvData >> inviteCount;
336
337 for (uint32 i = 0; i < inviteCount && i < CALENDAR_MAX_INVITES; ++i)
338 {
339 recvData >> invitee[i].ReadAsPacked();
340 recvData >> status[i] >> rank[i];
341 }
342 }
343 catch (ByteBufferException const&)
344 {
345 delete calendarEvent;
346 calendarEvent = nullptr;
347 throw;
348 }
349
351 if (inviteCount > 1)
352 trans = CharacterDatabase.BeginTransaction();
353
354 for (uint32 i = 0; i < inviteCount && i < CALENDAR_MAX_INVITES; ++i)
355 {
356 // 946684800 is 01/01/2000 00:00:00 - default response time
357 CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), calendarEvent->GetEventId(), invitee[i], guid, 946684800, CalendarInviteStatus(status[i]), CalendarModerationRank(rank[i]), "");
358 sCalendarMgr->AddInvite(calendarEvent, invite, trans);
359 }
360
361 if (inviteCount > 1)
362 CharacterDatabase.CommitTransaction(trans);
363 }
364
365 sCalendarMgr->AddEvent(calendarEvent, CALENDAR_SENDTYPE_ADD);
366}
#define sCalendarMgr
Definition: CalendarMgr.h:344
@ CALENDAR_ERROR_INTERNAL
Definition: CalendarMgr.h:98
@ CALENDAR_ERROR_EVENT_PASSED
Definition: CalendarMgr.h:109
@ CALENDAR_ERROR_EVENTS_EXCEEDED
Definition: CalendarMgr.h:92
@ CALENDAR_ERROR_GUILD_EVENTS_EXCEEDED
Definition: CalendarMgr.h:91
@ CALENDAR_ERROR_GUILD_PLAYER_NOT_IN_GUILD
Definition: CalendarMgr.h:99
CalendarModerationRank
Definition: CalendarMgr.h:44
@ CALENDAR_RANK_PLAYER
Definition: CalendarMgr.h:45
@ CALENDAR_SENDTYPE_ADD
Definition: CalendarMgr.h:53
CalendarEventType
Definition: CalendarMgr.h:58
CalendarInviteStatus
Definition: CalendarMgr.h:75
@ CALENDAR_STATUS_NOT_SIGNED_UP
Definition: CalendarMgr.h:83
@ CALENDAR_MAX_EVENTS
Definition: CalendarMgr.h:128
@ CALENDAR_MAX_INVITES
Definition: CalendarMgr.h:130
@ CALENDAR_MAX_GUILD_EVENTS
Definition: CalendarMgr.h:129
@ CALENDAR_CREATE_EVENT_COOLDOWN
Definition: CalendarMgr.h:131
bool validUtf8String(WorldPacket &recvData, std::string &s, std::string action, ObjectGuid playerGUID)
bool IsGuildAnnouncement() const
Definition: CalendarMgr.h:253
void SetGuildId(uint32 guildId)
Definition: CalendarMgr.h:228
bool IsGuildEvent() const
Definition: CalendarMgr.h:252
uint64 GetEventId() const
Definition: CalendarMgr.h:223
uint32 GetGuildId() const
Definition: Player.h:1850
time_t GetCalendarEventCreationCooldown() const
Definition: WorldSession.h:527
void SetCalendarEventCreationCooldown(time_t cooldown)
Definition: WorldSession.h:528
uint32 ReadPackedTime()
Definition: ByteBuffer.cpp:96

◆ HandleCalendarArenaTeam()

void WorldSession::HandleCalendarArenaTeam ( WorldPacket recvData)

Definition at line 216 of file CalendarHandler.cpp.

217{
218 LOG_DEBUG("network", "CMSG_CALENDAR_ARENA_TEAM [{}]", _player->GetGUID().ToString());
219
220 uint32 arenaTeamId;
221 recvData >> arenaTeamId;
222
223 if (ArenaTeam* team = sArenaTeamMgr->GetArenaTeamById(arenaTeamId))
224 team->MassInviteToEvent(this);
225}

◆ HandleCalendarComplain()

void WorldSession::HandleCalendarComplain ( WorldPacket recvData)

Definition at line 766 of file CalendarHandler.cpp.

767{
768 ObjectGuid guid = _player->GetGUID();
769 uint64 eventId;
770 ObjectGuid complainGUID;
771
772 recvData >> eventId >> complainGUID;
773 LOG_DEBUG("network", "CMSG_CALENDAR_COMPLAIN [{}] EventId [{}] guid [{}]", guid.ToString(), eventId, complainGUID.ToString());
774
775 // what to do with complains?
776}

◆ HandleCalendarCopyEvent()

void WorldSession::HandleCalendarCopyEvent ( WorldPacket recvData)

Definition at line 436 of file CalendarHandler.cpp.

437{
438 ObjectGuid guid = _player->GetGUID();
439 uint64 eventId;
440 uint64 inviteId;
441 uint32 eventTime;
442
443 recvData >> eventId >> inviteId;
444 recvData.ReadPackedTime(eventTime);
445 LOG_DEBUG("network", "CMSG_CALENDAR_COPY_EVENT [{}], EventId [{}] inviteId [{}] Time: {}", guid.ToString(), eventId, inviteId, eventTime);
446
447 // prevent events in the past
448 // To Do: properly handle timezones and remove the "- time_t(86400L)" hack
449 if (time_t(eventTime) < (GameTime::GetGameTime().count() - time_t(86400L)))
450 {
451 recvData.rfinish();
452 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_PASSED);
453 return;
454 }
455
456 if (CalendarEvent* oldEvent = sCalendarMgr->GetEvent(eventId))
457 {
458 // Ensure that the player has access to the event
459 if (oldEvent->IsGuildEvent() || oldEvent->IsGuildAnnouncement())
460 {
461 if (oldEvent->GetGuildId() != _player->GetGuildId())
462 {
463 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
464 return;
465 }
466 }
467 else
468 {
469 if (oldEvent->GetCreatorGUID() != guid)
470 {
471 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
472 return;
473 }
474 }
475
476 // Check if the player reached the max number of events allowed to create
477 if (oldEvent->IsGuildEvent() || oldEvent->IsGuildAnnouncement())
478 {
479 if (sCalendarMgr->GetGuildEvents(_player->GetGuildId()).size() >= CALENDAR_MAX_GUILD_EVENTS)
480 {
481 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_GUILD_EVENTS_EXCEEDED);
482 return;
483 }
484 }
485 else
486 {
487 if (sCalendarMgr->GetEventsCreatedBy(guid).size() >= CALENDAR_MAX_EVENTS)
488 {
489 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENTS_EXCEEDED);
490 return;
491 }
492 }
493
495 {
496 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_INTERNAL);
497 return;
498 }
500
501 CalendarEvent* newEvent = new CalendarEvent(*oldEvent, sCalendarMgr->GetFreeEventId());
502 newEvent->SetEventTime(time_t(eventTime));
503 sCalendarMgr->AddEvent(newEvent, CALENDAR_SENDTYPE_COPY);
504
505 CalendarInviteStore invites = sCalendarMgr->GetEventInvites(eventId);
507 if (invites.size() > 1)
508 trans = CharacterDatabase.BeginTransaction();
509
510 for (CalendarInviteStore::const_iterator itr = invites.begin(); itr != invites.end(); ++itr)
511 sCalendarMgr->AddInvite(newEvent, new CalendarInvite(**itr, sCalendarMgr->GetFreeInviteId(), newEvent->GetEventId()), trans);
512
513 if (invites.size() > 1)
514 CharacterDatabase.CommitTransaction(trans);
515 // should we change owner when somebody makes a copy of event owned by another person?
516 }
517 else
518 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
519}
@ CALENDAR_ERROR_EVENT_INVALID
Definition: CalendarMgr.h:96
std::vector< CalendarInvite * > CalendarInviteStore
Definition: CalendarMgr.h:273
@ CALENDAR_SENDTYPE_COPY
Definition: CalendarMgr.h:54
void SetEventTime(time_t eventTime)
Definition: CalendarMgr.h:243

◆ HandleCalendarEventInvite()

void WorldSession::HandleCalendarEventInvite ( WorldPacket recvData)

Definition at line 521 of file CalendarHandler.cpp.

522{
523 LOG_DEBUG("network", "CMSG_CALENDAR_EVENT_INVITE");
524
525 ObjectGuid playerGuid = _player->GetGUID();
526
527 uint64 eventId;
528 uint64 inviteId;
529 std::string name;
530 bool isPreInvite;
531 bool isGuildEvent;
532
533 ObjectGuid inviteeGuid;
534 uint32 inviteeTeamId = TEAM_NEUTRAL;
535 uint32 inviteeGuildId = 0;
536
537 recvData >> eventId >> inviteId >> name >> isPreInvite >> isGuildEvent;
538
539 if (Player* player = ObjectAccessor::FindPlayerByName(name.c_str(), false))
540 {
541 // Invitee is online
542 inviteeGuid = player->GetGUID();
543 inviteeTeamId = player->GetTeamId();
544 inviteeGuildId = player->GetGuildId();
545 }
546 else
547 {
548 // xinef: Get Data From global storage
549 if (ObjectGuid guid = sCharacterCache->GetCharacterGuidByName(name))
550 {
551 if (CharacterCacheEntry const* playerData = sCharacterCache->GetCharacterCacheByGuid(guid))
552 {
553 inviteeGuid = guid;
554 inviteeTeamId = Player::TeamIdForRace(playerData->Race);
555 inviteeGuildId = playerData->GuildId;
556 }
557 }
558 }
559
560 if (!inviteeGuid)
561 {
562 sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_PLAYER_NOT_FOUND);
563 return;
564 }
565
566 if (_player->GetTeamId() != inviteeTeamId && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CALENDAR))
567 {
568 sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_NOT_ALLIED);
569 return;
570 }
571
572 // xinef: sync query
573 if (QueryResult result = CharacterDatabase.Query("SELECT flags FROM character_social WHERE guid = {} AND friend = {}", inviteeGuid.GetCounter(), playerGuid.GetCounter()))
574 {
575 Field* fields = result->Fetch();
576 if (fields[0].Get<uint8>() & SOCIAL_FLAG_IGNORED)
577 {
578 sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_IGNORING_YOU_S, name.c_str());
579 return;
580 }
581 }
582
583 if (!isPreInvite)
584 {
585 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
586 {
587 if (calendarEvent->IsGuildEvent() && calendarEvent->GetGuildId() == inviteeGuildId)
588 {
589 // we can't invite guild members to guild events
590 sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_NO_GUILD_INVITES);
591 return;
592 }
593
594 // 946684800 is 01/01/2000 00:00:00 - default response time
595 CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), eventId, inviteeGuid, playerGuid, 946684800, CALENDAR_STATUS_INVITED, CALENDAR_RANK_PLAYER, "");
596 sCalendarMgr->AddInvite(calendarEvent, invite);
597 }
598 else
599 sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_EVENT_INVALID);
600 }
601 else
602 {
603 if (isGuildEvent && inviteeGuildId == _player->GetGuildId())
604 {
605 sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_NO_GUILD_INVITES);
606 return;
607 }
608
609 // 946684800 is 01/01/2000 00:00:00 - default response time
610 CalendarInvite* invite = new CalendarInvite(inviteId, 0, inviteeGuid, playerGuid, 946684800, CALENDAR_STATUS_INVITED, CALENDAR_RANK_PLAYER, "");
611 sCalendarMgr->SendCalendarEventInvite(*invite);
612 }
613}
std::shared_ptr< ResultSet > QueryResult
@ CALENDAR_ERROR_NOT_ALLIED
Definition: CalendarMgr.h:102
@ CALENDAR_ERROR_NO_GUILD_INVITES
Definition: CalendarMgr.h:121
@ CALENDAR_ERROR_IGNORING_YOU_S
Definition: CalendarMgr.h:103
@ CALENDAR_ERROR_PLAYER_NOT_FOUND
Definition: CalendarMgr.h:101
@ CALENDAR_STATUS_INVITED
Definition: CalendarMgr.h:76
@ CONFIG_ALLOW_TWO_SIDE_INTERACTION_CALENDAR
Definition: IWorld.h:77
Class used to access individual fields of database query result.
Definition: Field.h:99

◆ HandleCalendarEventModeratorStatus()

void WorldSession::HandleCalendarEventModeratorStatus ( WorldPacket recvData)

Definition at line 737 of file CalendarHandler.cpp.

738{
739 ObjectGuid guid = _player->GetGUID();
740 ObjectGuid invitee;
741 uint64 eventId;
742 uint64 inviteId;
743 uint64 ownerInviteId; // isn't it sender's inviteId?
744 uint8 rank;
745
746 recvData>> invitee.ReadAsPacked();
747 recvData >> eventId >> inviteId >> ownerInviteId >> rank;
748 LOG_DEBUG("network", "CMSG_CALENDAR_EVENT_MODERATOR_STATUS [{}] EventId [{}] ownerInviteId [{}], Invitee ([{}] id: [{}], rank {}",
749 guid.ToString(), eventId, ownerInviteId, invitee.ToString(), inviteId, rank);
750
751 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
752 {
753 if (CalendarInvite* invite = sCalendarMgr->GetInvite(inviteId))
754 {
755 invite->SetRank(CalendarModerationRank(rank));
756 sCalendarMgr->UpdateInvite(invite);
757 sCalendarMgr->SendCalendarEventModeratorStatusAlert(*calendarEvent, *invite);
758 }
759 else
760 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_NO_INVITE); // correct?
761 }
762 else
763 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
764}
@ CALENDAR_ERROR_NO_INVITE
Definition: CalendarMgr.h:117

◆ HandleCalendarEventRemoveInvite()

void WorldSession::HandleCalendarEventRemoveInvite ( WorldPacket recvData)

Definition at line 677 of file CalendarHandler.cpp.

678{
679 ObjectGuid guid = _player->GetGUID();
680 ObjectGuid invitee;
681 uint64 eventId;
682 uint64 ownerInviteId; // isn't it sender's inviteId?
683 uint64 inviteId;
684
685 recvData>> invitee.ReadAsPacked();
686 recvData >> inviteId >> ownerInviteId >> eventId;
687
688 LOG_DEBUG("network", "CMSG_CALENDAR_EVENT_REMOVE_INVITE [{}] EventId [{}], ownerInviteId [{}], Invitee ([{}] id: [{}])",
689 guid.ToString(), eventId, ownerInviteId, invitee.ToString(), inviteId);
690
691 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
692 {
693 if (calendarEvent->GetCreatorGUID() == invitee)
694 {
695 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_DELETE_CREATOR_FAILED);
696 return;
697 }
698
699 sCalendarMgr->RemoveInvite(inviteId, eventId, guid);
700 }
701 else
702 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_NO_INVITE);
703}
@ CALENDAR_ERROR_DELETE_CREATOR_FAILED
Definition: CalendarMgr.h:111

◆ HandleCalendarEventRsvp()

void WorldSession::HandleCalendarEventRsvp ( WorldPacket recvData)

Definition at line 641 of file CalendarHandler.cpp.

642{
643 ObjectGuid guid = _player->GetGUID();
644 uint64 eventId;
645 uint64 inviteId;
646 uint32 status;
647
648 recvData >> eventId >> inviteId >> status;
649 LOG_DEBUG("network", "CMSG_CALENDAR_EVENT_RSVP [{}] EventId [{}], InviteId [{}], status {}",
650 guid.ToString(), eventId, inviteId, status);
651
652 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
653 {
654 // i think we still should be able to remove self from locked events
655 if (status != CALENDAR_STATUS_REMOVED && calendarEvent->GetFlags() & CALENDAR_FLAG_INVITES_LOCKED)
656 {
657 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_LOCKED);
658 return;
659 }
660
661 if (CalendarInvite* invite = sCalendarMgr->GetInvite(inviteId))
662 {
663 invite->SetStatus(CalendarInviteStatus(status));
664 invite->SetStatusTime(GameTime::GetGameTime().count());
665
666 sCalendarMgr->UpdateInvite(invite);
667 sCalendarMgr->SendCalendarEventStatus(*calendarEvent, *invite);
668 sCalendarMgr->SendCalendarClearPendingAction(guid);
669 }
670 else
671 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_NO_INVITE); // correct?
672 }
673 else
674 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
675}
@ CALENDAR_ERROR_EVENT_LOCKED
Definition: CalendarMgr.h:110
@ CALENDAR_FLAG_INVITES_LOCKED
Definition: CalendarMgr.h:38
@ CALENDAR_STATUS_REMOVED
Definition: CalendarMgr.h:85

◆ HandleCalendarEventSignup()

void WorldSession::HandleCalendarEventSignup ( WorldPacket recvData)

Definition at line 615 of file CalendarHandler.cpp.

616{
617 ObjectGuid guid = _player->GetGUID();
618 uint64 eventId;
619 bool tentative;
620
621 recvData >> eventId >> tentative;
622 LOG_DEBUG("network", "CMSG_CALENDAR_EVENT_SIGNUP [{}] EventId [{}] Tentative {}", guid.ToString(), eventId, tentative);
623
624 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
625 {
626 if (calendarEvent->IsGuildEvent() && calendarEvent->GetGuildId() != _player->GetGuildId())
627 {
628 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_GUILD_PLAYER_NOT_IN_GUILD);
629 return;
630 }
631
633 CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), eventId, guid, guid, GameTime::GetGameTime().count(), status, CALENDAR_RANK_PLAYER, "");
634 sCalendarMgr->AddInvite(calendarEvent, invite);
635 sCalendarMgr->SendCalendarClearPendingAction(guid);
636 }
637 else
638 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
639}
@ CALENDAR_STATUS_TENTATIVE
Definition: CalendarMgr.h:84
@ CALENDAR_STATUS_SIGNED_UP
Definition: CalendarMgr.h:82

◆ HandleCalendarEventStatus()

void WorldSession::HandleCalendarEventStatus ( WorldPacket recvData)

Definition at line 705 of file CalendarHandler.cpp.

706{
707 ObjectGuid guid = _player->GetGUID();
708 ObjectGuid invitee;
709 uint64 eventId;
710 uint64 inviteId;
711 uint64 ownerInviteId; // isn't it sender's inviteId?
712 uint8 status;
713
714 recvData >> invitee.ReadAsPacked();
715 recvData >> eventId >> inviteId >> ownerInviteId >> status;
716 LOG_DEBUG("network", "CMSG_CALENDAR_EVENT_STATUS [{}] EventId [{}] ownerInviteId [{}], Invitee ({}) id: [{}], status {}",
717 guid.ToString(), eventId, ownerInviteId, invitee.ToString(), inviteId, status);
718
719 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
720 {
721 if (CalendarInvite* invite = sCalendarMgr->GetInvite(inviteId))
722 {
723 invite->SetStatus((CalendarInviteStatus)status);
724 invite->SetStatusTime(GameTime::GetGameTime().count());
725
726 sCalendarMgr->UpdateInvite(invite);
727 sCalendarMgr->SendCalendarEventStatus(*calendarEvent, *invite);
728 sCalendarMgr->SendCalendarClearPendingAction(invitee);
729 }
730 else
731 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_NO_INVITE); // correct?
732 }
733 else
734 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
735}

◆ HandleCalendarGetCalendar()

void WorldSession::HandleCalendarGetCalendar ( WorldPacket recvData)

Definition at line 52 of file CalendarHandler.cpp.

53{
54 ObjectGuid guid = _player->GetGUID();
55 LOG_DEBUG("network", "CMSG_CALENDAR_GET_CALENDAR [{}]", guid.ToString());
56
57 time_t currTime = GameTime::GetGameTime().count();
58
59 WorldPacket data(SMSG_CALENDAR_SEND_CALENDAR, 1000); // Average size if no instance
60
61 CalendarInviteStore invites = sCalendarMgr->GetPlayerInvites(guid);
62 data << uint32(invites.size());
63 for (CalendarInviteStore::const_iterator itr = invites.begin(); itr != invites.end(); ++itr)
64 {
65 data << uint64((*itr)->GetEventId());
66 data << uint64((*itr)->GetInviteId());
67 data << uint8((*itr)->GetStatus());
68 data << uint8((*itr)->GetRank());
69
70 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent((*itr)->GetEventId()))
71 {
72 data << uint8(calendarEvent->IsGuildEvent());
73 data << calendarEvent->GetCreatorGUID().WriteAsPacked();
74 }
75 else
76 {
77 data << uint8(0);
78 data << (*itr)->GetSenderGUID().WriteAsPacked();
79 }
80 }
81
82 CalendarEventStore playerEvents = sCalendarMgr->GetPlayerEvents(guid);
83 data << uint32(playerEvents.size());
84 for (CalendarEventStore::const_iterator itr = playerEvents.begin(); itr != playerEvents.end(); ++itr)
85 {
86 CalendarEvent* calendarEvent = *itr;
87
88 data << uint64(calendarEvent->GetEventId());
89 data << calendarEvent->GetTitle();
90 data << uint32(calendarEvent->GetType());
91 data.AppendPackedTime(calendarEvent->GetEventTime());
92 data << uint32(calendarEvent->GetFlags());
93 data << int32(calendarEvent->GetDungeonId());
94 data << calendarEvent->GetCreatorGUID().WriteAsPacked();
95 }
96
97 data << uint32(currTime); // server time
98 data.AppendPackedTime(currTime); // zone time
99
100 ByteBuffer dataBuffer;
101 uint32 boundCounter = 0;
102 for (uint8 i = 0; i < MAX_DIFFICULTY; ++i)
103 {
104 BoundInstancesMap const& m_boundInstances = sInstanceSaveMgr->PlayerGetBoundInstances(_player->GetGUID(), Difficulty(i));
105 for (BoundInstancesMap::const_iterator itr = m_boundInstances.begin(); itr != m_boundInstances.end(); ++itr)
106 {
107 if (itr->second.perm)
108 {
109 InstanceSave const* save = itr->second.save;
110 time_t resetTime = itr->second.extended ? save->GetExtendedResetTime() : save->GetResetTime();
111 dataBuffer << uint32(save->GetMapId());
112 dataBuffer << uint32(save->GetDifficulty());
113 dataBuffer << uint32(resetTime >= currTime ? resetTime - currTime : 0);
114 dataBuffer << ObjectGuid::Create<HighGuid::Instance>(save->GetInstanceId()); // instance save id as unique instance copy id
115 ++boundCounter;
116 }
117 }
118 }
119
120 data << uint32(boundCounter);
121 data.append(dataBuffer);
122
123 // pussywizard
124 uint32 relationTime = sWorld->getIntConfig(CONFIG_INSTANCE_RESET_TIME_RELATIVE_TIMESTAMP) + sWorld->getIntConfig(CONFIG_INSTANCE_RESET_TIME_HOUR) * HOUR; // set point in time (default 29.12.2005) + X hours
125 data << uint32(relationTime);
126
127 // Reuse variables
128 boundCounter = 0;
129 std::set<uint32> sentMaps;
130 dataBuffer.clear();
131
132 ResetTimeByMapDifficultyMap const& resets = sInstanceSaveMgr->GetResetTimeMap();
133 for (ResetTimeByMapDifficultyMap::const_iterator itr = resets.begin(); itr != resets.end(); ++itr)
134 {
135 uint32 mapId = PAIR32_LOPART(itr->first);
136 if (sentMaps.find(mapId) != sentMaps.end())
137 continue;
138
139 MapEntry const* mapEntry = sMapStore.LookupEntry(mapId);
140 if (!mapEntry || !mapEntry->IsRaid())
141 continue;
142
143 sentMaps.insert(mapId);
144
145 dataBuffer << int32(mapId);
146 time_t period = sInstanceSaveMgr->GetExtendedResetTimeFor(mapId, (Difficulty)PAIR32_HIPART(itr->first)) - itr->second;
147 dataBuffer << int32(period); // pussywizard: reset time period
148 dataBuffer << int32(0); // pussywizard: reset time offset, needed for other than 7-day periods if not aligned with relationTime
149 ++boundCounter;
150 }
151
152 data << uint32(boundCounter);
153 data.append(dataBuffer);
154
155 // TODO: Fix this, how we do know how many and what holidays to send?
156 data << uint32(sGameEventMgr->modifiedHolidays.size());
157 for (uint32 entry : sGameEventMgr->modifiedHolidays)
158 {
159 HolidaysEntry const* holiday = sHolidaysStore.LookupEntry(entry);
160
161 if (DisableMgr::IsDisabledFor(DISABLE_TYPE_GAME_EVENT, sGameEventMgr->GetHolidayEventId(holiday->Id), nullptr))
162 {
163 continue;
164 }
165
166 data << uint32(holiday->Id); // m_ID
167 data << uint32(holiday->Region); // m_region, might be looping
168 data << uint32(holiday->Looping); // m_looping, might be region
169 data << uint32(holiday->Priority); // m_priority
170 data << uint32(holiday->CalendarFilterType); // m_calendarFilterType
171
172 for (uint8 j = 0; j < MAX_HOLIDAY_DATES; ++j)
173 data << uint32(holiday->Date[j]); // 26 * m_date -- WritePackedTime ?
174
175 for (uint8 j = 0; j < MAX_HOLIDAY_DURATIONS; ++j)
176 data << uint32(holiday->Duration[j]); // 10 * m_duration
177
178 for (uint8 j = 0; j < MAX_HOLIDAY_FLAGS; ++j)
179 data << uint32(holiday->CalendarFlags[j]); // 10 * m_calendarFlags
180
181 data << holiday->TextureFilename; // m_textureFilename (holiday name)
182 }
183
184 SendPacket(&data);
185}
constexpr auto HOUR
Definition: Common.h:57
std::unordered_set< CalendarEvent * > CalendarEventStore
Definition: CalendarMgr.h:274
@ DISABLE_TYPE_GAME_EVENT
Definition: DisableMgr.h:38
DBCStorage< HolidaysEntry > sHolidaysStore(Holidaysfmt)
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
uint16 PAIR32_HIPART(uint32 x)
Definition: ObjectDefines.h:92
uint16 PAIR32_LOPART(uint32 x)
Definition: ObjectDefines.h:97
#define sGameEventMgr
Definition: GameEventMgr.h:186
std::unordered_map< uint32, InstancePlayerBind > BoundInstancesMap
#define sInstanceSaveMgr
std::unordered_map< uint32, time_t > ResetTimeByMapDifficultyMap
@ CONFIG_INSTANCE_RESET_TIME_RELATIVE_TIMESTAMP
Definition: IWorld.h:243
@ CONFIG_INSTANCE_RESET_TIME_HOUR
Definition: IWorld.h:242
Difficulty
Definition: DBCEnums.h:271
#define MAX_DIFFICULTY
Definition: DBCEnums.h:288
#define MAX_HOLIDAY_FLAGS
#define MAX_HOLIDAY_DURATIONS
#define MAX_HOLIDAY_DATES
@ SMSG_CALENDAR_SEND_CALENDAR
Definition: Opcodes.h:1108
ObjectGuid GetCreatorGUID() const
Definition: CalendarMgr.h:226
CalendarEventType GetType() const
Definition: CalendarMgr.h:238
int32 GetDungeonId() const
Definition: CalendarMgr.h:241
std::string GetTitle() const
Definition: CalendarMgr.h:232
time_t GetEventTime() const
Definition: CalendarMgr.h:244
uint32 GetFlags() const
Definition: CalendarMgr.h:247
PackedGuid WriteAsPacked() const
Definition: ObjectGuid.h:318
time_t GetExtendedResetTime() const
uint32 GetInstanceId() const
uint32 GetMapId() const
Difficulty GetDifficulty() const
time_t GetResetTime() const
int32 CalendarFilterType
uint32 Duration[MAX_HOLIDAY_DURATIONS]
char const * TextureFilename
uint32 CalendarFlags[MAX_HOLIDAY_FLAGS]
uint32 Date[MAX_HOLIDAY_DATES]
bool IsRaid() const
void clear()
Definition: ByteBuffer.h:122

◆ HandleCalendarGetEvent()

void WorldSession::HandleCalendarGetEvent ( WorldPacket recvData)

Definition at line 187 of file CalendarHandler.cpp.

188{
189 uint64 eventId;
190 recvData >> eventId;
191
192 LOG_DEBUG("network", "CMSG_CALENDAR_GET_EVENT. Player [{}] Event [{}]", _player->GetGUID().ToString(), eventId);
193
194 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
195 sCalendarMgr->SendCalendarEvent(_player->GetGUID(), *calendarEvent, CALENDAR_SENDTYPE_GET);
196 else
197 sCalendarMgr->SendCalendarCommandResult(_player->GetGUID(), CALENDAR_ERROR_EVENT_INVALID);
198}
@ CALENDAR_SENDTYPE_GET
Definition: CalendarMgr.h:52

◆ HandleCalendarGetNumPending()

void WorldSession::HandleCalendarGetNumPending ( WorldPacket recvData)

Definition at line 778 of file CalendarHandler.cpp.

779{
780 ObjectGuid guid = _player->GetGUID();
781 uint32 pending = sCalendarMgr->GetPlayerNumPending(guid);
782
783 LOG_DEBUG("network", "CMSG_CALENDAR_GET_NUM_PENDING: [{}] Pending: {}", guid.ToString(), pending);
784
786 data << uint32(pending);
787 SendPacket(&data);
788}
@ SMSG_CALENDAR_SEND_NUM_PENDING
Definition: Opcodes.h:1126

◆ HandleCalendarGuildFilter()

void WorldSession::HandleCalendarGuildFilter ( WorldPacket recvData)

Definition at line 200 of file CalendarHandler.cpp.

201{
202 LOG_DEBUG("network", "CMSG_CALENDAR_GUILD_FILTER [{}]", _player->GetGUID().ToString());
203
204 uint32 minLevel;
205 uint32 maxLevel;
206 uint32 minRank;
207
208 recvData >> minLevel >> maxLevel >> minRank;
209
210 if (Guild* guild = sGuildMgr->GetGuildById(_player->GetGuildId()))
211 guild->MassInviteToEvent(this, minLevel, maxLevel, minRank);
212
213 LOG_DEBUG("network", "CMSG_CALENDAR_GUILD_FILTER: Min level [{}], Max level [{}], Min rank [{}]", minLevel, maxLevel, minRank);
214}
#define sGuildMgr
Definition: GuildMgr.h:51
Definition: Guild.h:295

◆ HandleCalendarRemoveEvent()

void WorldSession::HandleCalendarRemoveEvent ( WorldPacket recvData)

Definition at line 425 of file CalendarHandler.cpp.

426{
427 ObjectGuid guid = _player->GetGUID();
428 uint64 eventId;
429
430 recvData >> eventId;
431 recvData.rfinish(); // Skip flags & invite ID, we don't use them
432
433 sCalendarMgr->RemoveEvent(eventId, guid);
434}

◆ HandleCalendarUpdateEvent()

void WorldSession::HandleCalendarUpdateEvent ( WorldPacket recvData)

Definition at line 368 of file CalendarHandler.cpp.

369{
370 ObjectGuid guid = _player->GetGUID();
371 time_t oldEventTime;
372
373 uint64 eventId;
374 uint64 inviteId;
375 std::string title;
376 std::string description;
377 uint8 type;
378 uint8 repetitionType;
379 uint32 maxInvites;
380 int32 dungeonId;
381 uint32 eventPackedTime;
382 uint32 timeZoneTime;
383 uint32 flags;
384
385 recvData >> eventId >> inviteId >> title >> description >> type >> repetitionType >> maxInvites >> dungeonId;
386 recvData.ReadPackedTime(eventPackedTime);
387 recvData.ReadPackedTime(timeZoneTime);
388 recvData >> flags;
389
390 // prevent attacks with non-utf8 chars -> with multiple packets it will hang up the db due to errors.
391 if (!validUtf8String(recvData, title, "update", guid) || title.size() > 31 || !validUtf8String(recvData, description, "update", guid) || description.size() > 255)
392 return;
393
394 // prevent events in the past
395 // To Do: properly handle timezones and remove the "- time_t(86400L)" hack
396 if (time_t(eventPackedTime) < (GameTime::GetGameTime().count() - time_t(86400L)))
397 {
398 recvData.rfinish();
399 return;
400 }
401
402 LOG_DEBUG("network", "CMSG_CALENDAR_UPDATE_EVENT [{}] EventId [{}], InviteId [{}] Title {}, Description {}, type {} "
403 "Repeatable {}, MaxInvites {}, Dungeon ID {}, Time {} Time2 {}, Flags {}",
404 guid.ToString(), eventId, inviteId, title, description, type, repetitionType, maxInvites, dungeonId, eventPackedTime, timeZoneTime, flags);
405
406 if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId))
407 {
408 oldEventTime = calendarEvent->GetEventTime();
409
410 calendarEvent->SetType(CalendarEventType(type));
411 calendarEvent->SetFlags(flags);
412 calendarEvent->SetEventTime(time_t(eventPackedTime));
413 calendarEvent->SetTimeZoneTime(time_t(timeZoneTime)); // Not sure, seems constant from the little sniffs we have
414 calendarEvent->SetDungeonId(dungeonId);
415 calendarEvent->SetTitle(title);
416 calendarEvent->SetDescription(description);
417
418 sCalendarMgr->UpdateEvent(calendarEvent);
419 sCalendarMgr->SendCalendarEventUpdateAlert(*calendarEvent, oldEventTime);
420 }
421 else
422 sCalendarMgr->SendCalendarCommandResult(guid, CALENDAR_ERROR_EVENT_INVALID);
423}

◆ HandleCancelAuraOpcode()

void WorldSession::HandleCancelAuraOpcode ( WorldPacket recvPacket)

Definition at line 488 of file SpellHandler.cpp.

489{
490 uint32 spellId;
491 recvPacket >> spellId;
492
493 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
494 if (!spellInfo)
495 return;
496
497 // not allow remove spells with attr SPELL_ATTR0_NO_AURA_CANCEL
499 {
500 return;
501 }
502
503 // channeled spell case (it currently casted then)
504 if (spellInfo->IsChanneled())
505 {
507 if (curSpell->m_spellInfo->Id == spellId)
509 return;
510 }
511
512 // non channeled case:
513 // don't allow remove non positive spells
514 // don't allow cancelling passive auras (some of them are visible)
515 if (!spellInfo->IsPositive() || spellInfo->IsPassive())
516 {
517 return;
518 }
519
520 // maybe should only remove one buff when there are multiple?
522}
@ CURRENT_CHANNELED_SPELL
Definition: Unit.h:980
@ AURA_REMOVE_BY_CANCEL
@ SPELL_ATTR0_NO_AURA_CANCEL
void RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4625
void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed=true, bool withInstant=true, bool bySelf=false)
Definition: Unit.cpp:3990
Spell * GetCurrentSpell(CurrentSpellTypes spellType) const
Definition: Unit.h:2058
bool IsPassive() const
Definition: SpellInfo.cpp:1081
bool IsChanneled() const
Definition: SpellInfo.cpp:1239
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:412
bool IsPositive() const
Definition: SpellInfo.cpp:1220

◆ HandleCancelAutoRepeatSpellOpcode()

void WorldSession::HandleCancelAutoRepeatSpellOpcode ( WorldPacket recvPacket)

Definition at line 566 of file SpellHandler.cpp.

567{
568 // may be better send SMSG_CANCEL_AUTO_REPEAT?
569 // cancel and prepare for deleting
571}
@ CURRENT_AUTOREPEAT_SPELL
Definition: Unit.h:981

◆ HandleCancelCastOpcode()

void WorldSession::HandleCancelCastOpcode ( WorldPacket recvPacket)

Definition at line 476 of file SpellHandler.cpp.

477{
478 uint32 spellId;
479
480 recvPacket.read_skip<uint8>(); // counter, increments with every CANCEL packet, don't use for now
481 recvPacket >> spellId;
482
484 if (_player->IsNonMeleeSpellCast(false))
485 _player->InterruptNonMeleeSpells(false, spellId, false, true);
486}
@ CURRENT_MELEE_SPELL
Definition: Unit.h:978
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true, bool bySelf=false)
Definition: Unit.cpp:4057
bool IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled=false, bool skipAutorepeat=false, bool isAutoshoot=false, bool skipInstant=true) const
Definition: Unit.cpp:4027

◆ HandleCancelChanneling()

void WorldSession::HandleCancelChanneling ( WorldPacket recvData)

Definition at line 573 of file SpellHandler.cpp.

574{
575 uint32 spellID = 0;
576 recvData >> spellID;
577
578 // ignore for remote control state (for player case)
579 Unit* mover = _player->m_mover;
580 if (!mover)
581 {
582 return;
583 }
584
585 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellID);
586 if (!spellInfo)
587 {
588 return;
589 }
590
591 // not allow remove spells with attr SPELL_ATTR0_NO_AURA_CANCEL
593 {
594 return;
595 }
596
598 if (!spell || spell->GetSpellInfo()->Id != spellInfo->Id)
599 {
600 return;
601 }
602
604}
SafeUnitPointer m_mover
Definition: Player.h:2281
SpellInfo const * GetSpellInfo() const
Definition: Spell.h:574
uint32 Id
Definition: SpellInfo.h:318

◆ HandleCancelGrowthAuraOpcode()

void WorldSession::HandleCancelGrowthAuraOpcode ( WorldPacket recvPacket)

Definition at line 562 of file SpellHandler.cpp.

563{
564}

◆ HandleCancelMountAuraOpcode()

void WorldSession::HandleCancelMountAuraOpcode ( WorldPacket recvData)

Definition at line 1533 of file MiscHandler.cpp.

1534{
1535 LOG_DEBUG("network", "WORLD: CMSG_CANCEL_MOUNT_AURA");
1536
1537 //If player is not mounted, so go out :)
1538 if (!_player->IsMounted()) // not blizz like; no any messages on blizz
1539 {
1541 return;
1542 }
1543
1544 if (_player->IsInFlight()) // not blizz like; no any messages on blizz
1545 {
1547 return;
1548 }
1549
1550 _player->Dismount();
1552}
@ LANG_CHAR_NON_MOUNTED
Definition: Language.h:54
@ LANG_YOU_IN_FLIGHT
Definition: Language.h:50
@ SPELL_AURA_MOUNTED
virtual void SendSysMessage(std::string_view str, bool escapeCharacters=false)
Definition: Chat.cpp:103
void Dismount()
Definition: Unit.cpp:13428
bool IsMounted() const
Definition: Unit.h:1540

◆ HandleCancelTempEnchantmentOpcode()

void WorldSession::HandleCancelTempEnchantmentOpcode ( WorldPacket recvData)

Definition at line 1549 of file ItemHandler.cpp.

1550{
1551 LOG_DEBUG("network", "WORLD: CMSG_CANCEL_TEMP_ENCHANTMENT");
1552
1553 uint32 eslot;
1554
1555 recvData >> eslot;
1556
1557 // apply only to equipped item
1559 return;
1560
1562
1563 if (!item)
1564 return;
1565
1567 return;
1568
1571}
@ TEMP_ENCHANTMENT_SLOT
Definition: Item.h:164
uint32 GetEnchantmentId(EnchantmentSlot slot) const
Definition: Item.h:295
void ClearEnchantment(EnchantmentSlot slot)
Definition: Item.cpp:962

◆ HandleCancelTradeOpcode()

void WorldSession::HandleCancelTradeOpcode ( WorldPacket recvPacket)

Definition at line 536 of file TradeHandler.cpp.

537{
538 _player->TradeCancel(true);
539}
void TradeCancel(bool sendback)

◆ HandleCastSpellOpcode()

void WorldSession::HandleCastSpellOpcode ( WorldPacket recvPacket)

Definition at line 337 of file SpellHandler.cpp.

338{
339 uint32 spellId;
340 uint8 castCount, castFlags;
341 recvPacket >> castCount >> spellId >> castFlags;
342 TriggerCastFlags triggerFlag = TRIGGERED_NONE;
343
344 uint32 oldSpellId = spellId;
345
346 LOG_DEBUG("network", "WORLD: got cast spell packet, castCount: {}, spellId: {}, castFlags: {}, data length = {}", castCount, spellId, castFlags, (uint32)recvPacket.size());
347
348 // ignore for remote control state (for player case)
349 Unit* mover = _player->m_mover;
350 if (mover != _player && mover->GetTypeId() == TYPEID_PLAYER)
351 {
352 recvPacket.rfinish(); // prevent spam at ignore packet
353 return;
354 }
355
356 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
357
358 if (!spellInfo)
359 {
360 LOG_ERROR("network.opcode", "WORLD: unknown spell id {}", spellId);
361 recvPacket.rfinish(); // prevent spam at ignore packet
362 return;
363 }
364
365 // client provided targets
366 SpellCastTargets targets;
367 targets.Read(recvPacket, mover);
368 HandleClientCastFlags(recvPacket, castFlags, targets);
369
370 // not have spell in spellbook
371 if (mover->GetTypeId() == TYPEID_PLAYER)
372 {
373 // not have spell in spellbook or spell passive and not casted by client
374 if( !(spellInfo->Targets & TARGET_FLAG_GAMEOBJECT_ITEM) && (!mover->ToPlayer()->HasActiveSpell(spellId) || spellInfo->IsPassive()) )
375 {
376 bool allow = false;
377
378 // allow casting of unknown spells for special lock cases
379 if (GameObject* go = targets.GetGOTarget())
380 {
381 if (go->GetSpellForLock(mover->ToPlayer()) == spellInfo)
382 {
383 allow = true;
384 }
385 }
386
387 // TODO: Preparation for #23204
388 // allow casting of spells triggered by clientside periodic trigger auras
389 /*
390 if (caster->HasAuraTypeWithTriggerSpell(SPELL_AURA_PERIODIC_TRIGGER_SPELL_FROM_CLIENT, spellId))
391 {
392 allow = true;
393 triggerFlag = TRIGGERED_FULL_MASK;
394 }
395 */
396
397 if (!allow)
398 return;
399 }
400 }
401 else
402 {
403 // pussywizard: casting player's spells from vehicle when seat allows it
404 // if ANYTHING CHANGES in this function, INFORM ME BEFORE applying!!!
405 if (Vehicle* veh = mover->GetVehicleKit())
406 if (const VehicleSeatEntry* seat = veh->GetSeatForPassenger(_player))
407 if (seat->m_flags & VEHICLE_SEAT_FLAG_CAN_ATTACK || spellInfo->Effects[EFFECT_0].Effect == SPELL_EFFECT_OPEN_LOCK /*allow looting from vehicle, but only if player has required spell (all necessary opening spells are in playercreateinfo_spell)*/)
408 if ((mover->GetTypeId() == TYPEID_UNIT && !mover->ToCreature()->HasSpell(spellId)) || spellInfo->IsPassive()) // the creature can't cast that spell, check player instead
409 {
410 if( !(spellInfo->Targets & TARGET_FLAG_GAMEOBJECT_ITEM) && (!_player->HasActiveSpell (spellId) || spellInfo->IsPassive()) )
411 {
412 //cheater? kick? ban?
413 recvPacket.rfinish(); // prevent spam at ignore packet
414 return;
415 }
416
417 // at this point, player is a valid caster
418 // swapping the mover will stop the check below at == TYPEID_UNIT, so everything works fine
419 mover = _player;
420 }
421
422 // not have spell in spellbook or spell passive and not casted by client
423 if ((mover->GetTypeId() == TYPEID_UNIT && !mover->ToCreature()->HasSpell(spellId)) || spellInfo->IsPassive())
424 {
425 //cheater? kick? ban?
426 recvPacket.rfinish(); // prevent spam at ignore packet
427 return;
428 }
429 }
430
431 sScriptMgr->ValidateSpellAtCastSpell(_player, oldSpellId, spellId, castCount, castFlags);
432
433 if (oldSpellId != spellId)
434 spellInfo = sSpellMgr->GetSpellInfo(spellId);
435
436 // Client is resending autoshot cast opcode when other spell is casted during shoot rotation
437 // Skip it to prevent "interrupt" message
440 {
441 recvPacket.rfinish();
442 return;
443 }
444
445 // can't use our own spells when we're in possession of another unit,
446 if (_player->isPossessing())
447 {
448 return;
449 }
450
451 // pussywizard: HandleClientCastFlags calls HandleMovementOpcodes, which can result in pretty much anything. Caster not in map will crash at GetMap() for spell difficulty in Spell constructor.
452 if (!mover->FindMap())
453 {
454 recvPacket.rfinish(); // prevent spam at ignore packet
455 return;
456 }
457
458 // auto-selection buff level base at target level (in spellInfo)
459 if (targets.GetUnitTarget())
460 {
461 SpellInfo const* actualSpellInfo = spellInfo->GetAuraRankForLevel(targets.GetUnitTarget()->getLevel());
462
463 // if rank not found then function return nullptr but in explicit cast case original spell can be casted and later failed with appropriate error message
464 if (actualSpellInfo)
465 spellInfo = actualSpellInfo;
466 }
467
468 Spell* spell = new Spell(mover, spellInfo, triggerFlag, ObjectGuid::Empty, false);
469
470 sScriptMgr->ValidateSpellAtCastSpellResult(_player, mover, spell, oldSpellId, spellId);
471
472 spell->m_cast_count = castCount; // set count of casts
473 spell->prepare(&targets);
474}
@ TYPEID_UNIT
Definition: ObjectGuid.h:37
@ TYPEID_PLAYER
Definition: ObjectGuid.h:38
TriggerCastFlags
Definition: SpellDefines.h:130
@ TRIGGERED_NONE
Definition: SpellDefines.h:131
@ TARGET_FLAG_GAMEOBJECT_ITEM
Definition: SpellInfo.h:60
@ EFFECT_0
Definition: SharedDefines.h:30
@ SPELL_EFFECT_OPEN_LOCK
bool HasSpell(uint32 spellID) const override
Definition: Creature.cpp:2797
Player * ToPlayer()
Definition: Object.h:195
TypeID GetTypeId() const
Definition: Object.h:121
Creature * ToCreature()
Definition: Object.h:197
Map * FindMap() const
Definition: Object.h:518
bool HasActiveSpell(uint32 spell) const
Definition: Player.cpp:3822
bool isPossessing() const
Definition: Unit.h:1871
Vehicle * GetVehicleKit() const
Definition: Unit.h:2348
void HandleClientCastFlags(WorldPacket &recvPacket, uint8 castFlags, SpellCastTargets &targets)
GameObject * GetGOTarget() const
Definition: Spell.cpp:258
void Read(ByteBuffer &data, Unit *caster)
Definition: Spell.cpp:120
Unit * GetUnitTarget() const
Definition: Spell.cpp:226
uint8 m_cast_count
Definition: Spell.h:524
SpellInfo const *const m_spellInfo
Definition: Spell.h:520
SpellInfo const * GetAuraRankForLevel(uint8 level) const
Definition: SpellInfo.cpp:2506
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > Effects
Definition: SpellInfo.h:391
uint32 Targets
Definition: SpellInfo.h:333
bool IsAutoRepeatRangedSpell() const
Definition: SpellInfo.cpp:1266

◆ HandleChangeSeatsOnControlledVehicle()

void WorldSession::HandleChangeSeatsOnControlledVehicle ( WorldPacket recvData)

Definition at line 58 of file VehicleHandler.cpp.

59{
60 LOG_DEBUG("network", "WORLD: Recvd CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE");
61
62 Unit* vehicle_base = GetPlayer()->GetVehicleBase();
63 if (!vehicle_base)
64 {
65 recvData.rfinish(); // prevent warnings spam
66 return;
67 }
68
70 if (!seat->CanSwitchFromSeat())
71 {
72 recvData.rfinish(); // prevent warnings spam
73 LOG_ERROR("network.opcode", "HandleChangeSeatsOnControlledVehicle, Opcode: {}, Player {} tried to switch seats but current seatflags {} don't permit that.",
74 recvData.GetOpcode(), GetPlayer()->GetGUID().ToString(), seat->m_flags);
75 return;
76 }
77
78 switch (recvData.GetOpcode())
79 {
81 GetPlayer()->ChangeSeat(-1, false);
82 break;
84 GetPlayer()->ChangeSeat(-1, true);
85 break;
87 {
88 ObjectGuid guid; // current vehicle guid
89 recvData >> guid.ReadAsPacked();
90
91 // pussywizard:
92 if (vehicle_base->GetGUID() != guid)
93 {
94 recvData.rfinish(); // prevent warnings spam
95 return;
96 }
97
98 MovementInfo movementInfo;
99 movementInfo.guid = guid;
100 ReadMovementInfo(recvData, &movementInfo);
101 vehicle_base->m_movementInfo = movementInfo;
102
103 ObjectGuid accessory; // accessory guid
104 recvData >> accessory.ReadAsPacked();
105
106 int8 seatId;
107 recvData >> seatId;
108
109 if (!accessory)
110 GetPlayer()->ChangeSeat(-1, seatId > 0); // prev/next
111 else if (Unit* vehUnit = ObjectAccessor::GetUnit(*GetPlayer(), accessory))
112 {
113 if (Vehicle* vehicle = vehUnit->GetVehicleKit())
114 if (vehicle->HasEmptySeat(seatId))
115 vehUnit->HandleSpellClick(GetPlayer(), seatId);
116 }
117 break;
118 }
120 {
121 ObjectGuid guid; // current vehicle guid
122 recvData >> guid.ReadAsPacked();
123
124 int8 seatId;
125 recvData >> seatId;
126
127 if (vehicle_base->GetGUID() == guid)
128 GetPlayer()->ChangeSeat(seatId);
129 else if (Unit* vehUnit = ObjectAccessor::GetUnit(*GetPlayer(), guid))
130 if (Vehicle* vehicle = vehUnit->GetVehicleKit())
131 if (vehicle->HasEmptySeat(seatId))
132 vehUnit->HandleSpellClick(GetPlayer(), seatId);
133 break;
134 }
135 default:
136 break;
137 }
138}
std::int8_t int8
Definition: Define.h:106
@ CMSG_REQUEST_VEHICLE_SWITCH_SEAT
Definition: Opcodes.h:1175
@ CMSG_REQUEST_VEHICLE_NEXT_SEAT
Definition: Opcodes.h:1174
@ CMSG_REQUEST_VEHICLE_PREV_SEAT
Definition: Opcodes.h:1173
@ CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE
Definition: Opcodes.h:1209
ObjectGuid guid
Definition: Object.h:266
Unit * GetVehicleBase() const
Definition: Unit.cpp:18774
void ChangeSeat(int8 seatId, bool next=true)
Definition: Unit.cpp:19730
VehicleSeatEntry const * GetSeatForPassenger(Unit const *passenger)
Definition: Vehicle.cpp:585
void ReadMovementInfo(WorldPacket &data, MovementInfo *mi)
bool CanSwitchFromSeat() const

◆ HandleChannelAnnouncements()

void WorldSession::HandleChannelAnnouncements ( WorldPacket recvPacket)

Definition at line 254 of file ChannelHandler.cpp.

255{
256 std::string channelName;
257 recvPacket >> channelName;
258
259 LOG_DEBUG("chat.system", "CMSG_CHANNEL_ANNOUNCEMENTS {} Channel: {}",
260 GetPlayerInfo(), channelName);
262 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
263 channel->Announce(GetPlayer());
264}
static ChannelMgr * forTeam(TeamId teamId)
Definition: ChannelMgr.cpp:33

◆ HandleChannelBan()

void WorldSession::HandleChannelBan ( WorldPacket recvPacket)

Definition at line 224 of file ChannelHandler.cpp.

225{
226 std::string channelName, targetName;
227 recvPacket >> channelName >> targetName;
228
229 LOG_DEBUG("chat.system", "CMSG_CHANNEL_BAN {} Channel: {}, Target: {}",
230 GetPlayerInfo(), channelName, targetName);
231 if (!normalizePlayerName(targetName))
232 return;
233
235 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
236 channel->Ban(GetPlayer(), targetName);
237}

◆ HandleChannelDeclineInvite()

void WorldSession::HandleChannelDeclineInvite ( WorldPacket recvPacket)

Definition at line 803 of file ChatHandler.cpp.

804{
805 // used only with EXTRA_LOGS
806 (void)recvPacket;
807
808 LOG_DEBUG("network", "Opcode {}", recvPacket.GetOpcode());
809}

◆ HandleChannelDisplayListQuery()

void WorldSession::HandleChannelDisplayListQuery ( WorldPacket recvPacket)

Definition at line 279 of file ChannelHandler.cpp.

280{
281 // this should be OK because the 2 function _were_ the same
282 HandleChannelList(recvPacket);
283}
void HandleChannelList(WorldPacket &recvPacket)

◆ HandleChannelInvite()

void WorldSession::HandleChannelInvite ( WorldPacket recvPacket)

Definition at line 194 of file ChannelHandler.cpp.

195{
196 std::string channelName, targetName;
197 recvPacket >> channelName >> targetName;
198
199 LOG_DEBUG("chat.system", "CMSG_CHANNEL_INVITE {} Channel: {}, Target: {}",
200 GetPlayerInfo(), channelName, targetName);
201 if (!normalizePlayerName(targetName))
202 return;
203
205 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
206 channel->Invite(GetPlayer(), targetName);
207}

◆ HandleChannelKick()

void WorldSession::HandleChannelKick ( WorldPacket recvPacket)

Definition at line 209 of file ChannelHandler.cpp.

210{
211 std::string channelName, targetName;
212 recvPacket >> channelName >> targetName;
213
214 LOG_DEBUG("chat.system", "CMSG_CHANNEL_KICK {} Channel: {}, Target: {}",
215 GetPlayerInfo(), channelName, targetName);
216 if (!normalizePlayerName(targetName))
217 return;
218
220 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
221 channel->Kick(GetPlayer(), targetName);
222}

◆ HandleChannelList()

void WorldSession::HandleChannelList ( WorldPacket recvPacket)

Definition at line 79 of file ChannelHandler.cpp.

80{
81 std::string channelName;
82 recvPacket >> channelName;
83
84 LOG_DEBUG("chat.system", "{} {} Channel: {}",
85 recvPacket.GetOpcode() == CMSG_CHANNEL_DISPLAY_LIST ? "CMSG_CHANNEL_DISPLAY_LIST" : "CMSG_CHANNEL_LIST",
86 GetPlayerInfo(), channelName);
88 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
89 channel->List(GetPlayer());
90}
@ CMSG_CHANNEL_DISPLAY_LIST
Definition: Opcodes.h:1008

◆ HandleChannelModerateOpcode()

void WorldSession::HandleChannelModerateOpcode ( WorldPacket recvPacket)

Definition at line 266 of file ChannelHandler.cpp.

267{
268 std::string channelName;
269 recvPacket >> channelName;
270
271 LOG_DEBUG("chat.system", "CMSG_CHANNEL_MODERATE {} Channel: {}",
272 GetPlayerInfo(), channelName);
273
275 if (Channel* chn = cMgr->GetChannel(channelName, GetPlayer()))
276 chn->ToggleModeration(GetPlayer());
277}

◆ HandleChannelModerator()

void WorldSession::HandleChannelModerator ( WorldPacket recvPacket)

Definition at line 134 of file ChannelHandler.cpp.

135{
136 std::string channelName, targetName;
137 recvPacket >> channelName >> targetName;
138
139 LOG_DEBUG("chat.system", "CMSG_CHANNEL_MODERATOR {} Channel: {}, Target: {}",
140 GetPlayerInfo(), channelName, targetName);
141 if (!normalizePlayerName(targetName))
142 return;
143
145 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
146 channel->SetModerator(GetPlayer(), targetName);
147}

◆ HandleChannelMute()

void WorldSession::HandleChannelMute ( WorldPacket recvPacket)

Definition at line 164 of file ChannelHandler.cpp.

165{
166 std::string channelName, targetName;
167 recvPacket >> channelName >> targetName;
168
169 LOG_DEBUG("chat.system", "CMSG_CHANNEL_MUTE {} Channel: {}, Target: {}",
170 GetPlayerInfo(), channelName, targetName);
171 if (!normalizePlayerName(targetName))
172 return;
173
175 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
176 channel->SetMute(GetPlayer(), targetName);
177}

◆ HandleChannelOwner()

void WorldSession::HandleChannelOwner ( WorldPacket recvPacket)

Definition at line 122 of file ChannelHandler.cpp.

123{
124 std::string channelName;
125 recvPacket >> channelName;
126
127 LOG_DEBUG("chat.system", "CMSG_CHANNEL_OWNER {} Channel: {}",
128 GetPlayerInfo(), channelName);
130 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
131 channel->SendWhoOwner(GetPlayer()->GetGUID());
132}

◆ HandleChannelPassword()

void WorldSession::HandleChannelPassword ( WorldPacket recvPacket)

Definition at line 92 of file ChannelHandler.cpp.

93{
94 std::string channelName, password;
95 recvPacket >> channelName >> password;
96
97 LOG_DEBUG("chat.system", "CMSG_CHANNEL_PASSWORD {} Channel: {}, Password: {}",
98 GetPlayerInfo(), channelName, password);
99 if (password.length() > MAX_CHANNEL_PASS_STR)
100 return;
101
103 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
104 channel->Password(GetPlayer(), password);
105}
#define MAX_CHANNEL_PASS_STR
Definition: ChannelMgr.h:27

◆ HandleChannelSetOwner()

void WorldSession::HandleChannelSetOwner ( WorldPacket recvPacket)

Definition at line 107 of file ChannelHandler.cpp.

108{
109 std::string channelName, targetName;
110 recvPacket >> channelName >> targetName;
111
112 LOG_DEBUG("chat.system", "CMSG_CHANNEL_SET_OWNER {} Channel: {}, Target: {}",
113 GetPlayerInfo(), channelName, targetName);
114 if (!normalizePlayerName(targetName))
115 return;
116
118 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
119 channel->SetOwner(GetPlayer(), targetName);
120}

◆ HandleChannelUnban()

void WorldSession::HandleChannelUnban ( WorldPacket recvPacket)

Definition at line 239 of file ChannelHandler.cpp.

240{
241 std::string channelName, targetName;
242 recvPacket >> channelName >> targetName;
243
244 LOG_DEBUG("chat.system", "CMSG_CHANNEL_UNBAN {} Channel: {}, Target: {}",
245 GetPlayerInfo(), channelName, targetName);
246 if (!normalizePlayerName(targetName))
247 return;
248
250 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
251 channel->UnBan(GetPlayer(), targetName);
252}

◆ HandleChannelUnmoderator()

void WorldSession::HandleChannelUnmoderator ( WorldPacket recvPacket)

Definition at line 149 of file ChannelHandler.cpp.

150{
151 std::string channelName, targetName;
152 recvPacket >> channelName >> targetName;
153
154 LOG_DEBUG("chat.system", "CMSG_CHANNEL_UNMODERATOR {} Channel: {}, Target: {}",
155 GetPlayerInfo(), channelName, targetName);
156 if (!normalizePlayerName(targetName))
157 return;
158
160 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
161 channel->UnsetModerator(GetPlayer(), targetName);
162}

◆ HandleChannelUnmute()

void WorldSession::HandleChannelUnmute ( WorldPacket recvPacket)

Definition at line 179 of file ChannelHandler.cpp.

180{
181 std::string channelName, targetName;
182 recvPacket >> channelName >> targetName;
183
184 LOG_DEBUG("chat.system", "CMSG_CHANNEL_UNMUTE {} Channel: {}, Target: {}",
185 GetPlayerInfo(), channelName, targetName);
186 if (!normalizePlayerName(targetName))
187 return;
188
190 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
191 channel->UnsetMute(GetPlayer(), targetName);
192}

◆ HandleChannelVoiceOnOpcode()

void WorldSession::HandleChannelVoiceOnOpcode ( WorldPacket recvData)

Definition at line 31 of file VoiceChatHandler.cpp.

32{
33 LOG_DEBUG("network", "WORLD: CMSG_CHANNEL_VOICE_ON");
34 // Enable Voice button in channel context menu
35}

◆ HandleCharacterAuraFrozen()

void WorldSession::HandleCharacterAuraFrozen ( PreparedQueryResult  result)

Definition at line 598 of file MiscHandler.cpp.

599{
600 if (!GetPlayer())
601 return;
602
603 ChatHandler handler = ChatHandler(this);
604
605 // Select
606 if (!result)
607 {
609 return;
610 }
611
612 // Header of the names
614
615 // Output of the results
616 do
617 {
618 Field* fields = result->Fetch();
619 std::string player = fields[0].Get<std::string>();
620 handler.PSendSysMessage(LANG_COMMAND_FROZEN_PLAYERS, player.c_str());
621 } while (result->NextRow());
622}
@ LANG_COMMAND_LIST_FREEZE
Definition: Language.h:1058
@ LANG_COMMAND_NO_FROZEN_PLAYERS
Definition: Language.h:1057
@ LANG_COMMAND_FROZEN_PLAYERS
Definition: Language.h:1059
std::enable_if_t< std::is_arithmetic_v< T >, T > Get() const
Definition: Field.h:113

◆ HandleCharCreateOpcode()

void WorldSession::HandleCharCreateOpcode ( WorldPacket recvPacket)
Todo:
what to if account already has characters of both races?
Todo:
check if cinematic already shown? (already logged in?; cinematic field)

Definition at line 267 of file CharacterHandler.cpp.

268{
269 std::shared_ptr<CharacterCreateInfo> createInfo = std::make_shared<CharacterCreateInfo>();
270
271 recvData >> createInfo->Name
272 >> createInfo->Race
273 >> createInfo->Class
274 >> createInfo->Gender
275 >> createInfo->Skin
276 >> createInfo->Face
277 >> createInfo->HairStyle
278 >> createInfo->HairColor
279 >> createInfo->FacialHair
280 >> createInfo->OutfitId;
281
283 {
284 if (uint32 mask = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED))
285 {
286 if (mask & (1 << Player::TeamIdForRace(createInfo->Race)))
287 {
289 return;
290 }
291 }
292 }
293
294 ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(createInfo->Class);
295 if (!classEntry)
296 {
298 LOG_ERROR("network.opcode", "Class ({}) not found in DBC while creating new char for account (ID: {}): wrong DBC files or cheater?", createInfo->Class, GetAccountId());
299 return;
300 }
301
302 ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(createInfo->Race);
303 if (!raceEntry)
304 {
306 LOG_ERROR("network.opcode", "Race ({}) not found in DBC while creating new char for account (ID: {}): wrong DBC files or cheater?", createInfo->Race, GetAccountId());
307 return;
308 }
309
310 // prevent character creating Expansion race without Expansion account
311 if (raceEntry->expansion > Expansion())
312 {
314 LOG_ERROR("network.opcode", "Expansion {} account:[{}] tried to Create character with expansion {} race ({})", Expansion(), GetAccountId(), raceEntry->expansion, createInfo->Race);
315 return;
316 }
317
318 // prevent character creating Expansion class without Expansion account
319 if (classEntry->expansion > Expansion())
320 {
322 LOG_ERROR("network.opcode", "Expansion {} account:[{}] tried to Create character with expansion {} class ({})", Expansion(), GetAccountId(), classEntry->expansion, createInfo->Class);
323 return;
324 }
325
327 {
328 uint32 raceMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK);
329 if ((1 << (createInfo->Race - 1)) & raceMaskDisabled)
330 {
332 return;
333 }
334
335 uint32 classMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_CLASSMASK);
336 if ((1 << (createInfo->Class - 1)) & classMaskDisabled)
337 {
339 return;
340 }
341 }
342
343 // prevent character creating with invalid name
344 if (!normalizePlayerName(createInfo->Name))
345 {
347 LOG_ERROR("network.opcode", "Account:[{}] but tried to Create character with empty [name] ", GetAccountId());
348 return;
349 }
350
351 // check name limitations
352 uint8 res = ObjectMgr::CheckPlayerName(createInfo->Name, true);
353 if (res != CHAR_NAME_SUCCESS)
354 {
356 return;
357 }
358
359 if (AccountMgr::IsPlayerAccount(GetSecurity()) && sObjectMgr->IsReservedName(createInfo->Name))
360 {
362 return;
363 }
364
365 // speedup check for heroic class disabled case
366 uint32 heroic_free_slots = sWorld->getIntConfig(CONFIG_HEROIC_CHARACTERS_PER_REALM);
367 if (heroic_free_slots == 0 && AccountMgr::IsPlayerAccount(GetSecurity()) && createInfo->Class == CLASS_DEATH_KNIGHT)
368 {
370 return;
371 }
372
373 // speedup check for heroic class disabled case
374 uint32 req_level_for_heroic = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_HEROIC_CHARACTER);
375 if (AccountMgr::IsPlayerAccount(GetSecurity()) && createInfo->Class == CLASS_DEATH_KNIGHT && req_level_for_heroic > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
376 {
378 return;
379 }
380
382 stmt->SetData(0, createInfo->Name);
383
385 .WithChainingPreparedCallback([this](QueryCallback& queryCallback, PreparedQueryResult result)
386 {
387 if (result)
388 {
389 SendCharCreate(CHAR_CREATE_NAME_IN_USE);
390 return;
391 }
392
394 stmt->SetData(0, GetAccountId());
395 queryCallback.SetNextQuery(LoginDatabase.AsyncQuery(stmt));
396 })
397 .WithChainingPreparedCallback([this](QueryCallback& queryCallback, PreparedQueryResult result)
398 {
399 uint64 acctCharCount = 0;
400 if (result)
401 {
402 Field* fields = result->Fetch();
403 acctCharCount = uint64(fields[0].Get<double>());
404 }
405
406 if (acctCharCount >= static_cast<uint64>(sWorld->getIntConfig(CONFIG_CHARACTERS_PER_ACCOUNT)))
407 {
409 return;
410 }
411
413 stmt->SetData(0, GetAccountId());
414 queryCallback.SetNextQuery(CharacterDatabase.AsyncQuery(stmt));
415 })
416 .WithChainingPreparedCallback([this, createInfo](QueryCallback& queryCallback, PreparedQueryResult result)
417 {
418 if (result)
419 {
420 Field* fields = result->Fetch();
421 createInfo->CharCount = uint8(fields[0].Get<uint64>()); // SQL's COUNT() returns uint64 but it will always be less than uint8.Max
422
423 if (createInfo->CharCount >= sWorld->getIntConfig(CONFIG_CHARACTERS_PER_REALM))
424 {
426 return;
427 }
428 }
429
430 bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || !AccountMgr::IsPlayerAccount(GetSecurity());
431 uint32 skipCinematics = sWorld->getIntConfig(CONFIG_SKIP_CINEMATICS);
432
433 std::function<void(PreparedQueryResult)> finalizeCharacterCreation = [this, createInfo](PreparedQueryResult result)
434 {
435 if (!sScriptMgr->CanAccountCreateCharacter(GetAccountId(), createInfo->Race, createInfo->Class))
436 {
438 return;
439 }
440 bool haveSameRace = false;
442 bool hasHeroicReqLevel = (heroicReqLevel == 0);
443 bool allowTwoSideAccounts = !sWorld->IsPvPRealm() || sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || !AccountMgr::IsPlayerAccount(GetSecurity());
444 uint32 skipCinematics = sWorld->getIntConfig(CONFIG_SKIP_CINEMATICS);
445 bool checkDeathKnightReqs = AccountMgr::IsPlayerAccount(GetSecurity()) && createInfo->Class == CLASS_DEATH_KNIGHT;
446
447 if (result)
448 {
449 TeamId teamId = Player::TeamIdForRace(createInfo->Race);
450 uint32 freeDeathKnightSlots = sWorld->getIntConfig(CONFIG_HEROIC_CHARACTERS_PER_REALM);
451
452 Field* field = result->Fetch();
453 uint8 accRace = field[1].Get<uint8>();
454
455 if (checkDeathKnightReqs)
456 {
457 uint8 accClass = field[2].Get<uint8>();
458 if (accClass == CLASS_DEATH_KNIGHT)
459 {
460 if (freeDeathKnightSlots > 0)
461 --freeDeathKnightSlots;
462
463 if (freeDeathKnightSlots == 0)
464 {
466 return;
467 }
468 }
469
470 if (!hasHeroicReqLevel)
471 {
472 uint8 accLevel = field[0].Get<uint8>();
473 if (accLevel >= heroicReqLevel)
474 hasHeroicReqLevel = true;
475 }
476 }
477
478 // need to check team only for first character
480 if (!allowTwoSideAccounts)
481 {
482 uint32 accTeam = 0;
483 if (accRace > 0)
484 accTeam = Player::TeamIdForRace(accRace);
485
486 if (accTeam != teamId)
487 {
489 return;
490 }
491 }
492
493 // search same race for cinematic or same class if need
495 while ((skipCinematics == 1 && !haveSameRace) || createInfo->Class == CLASS_DEATH_KNIGHT)
496 {
497 if (!result->NextRow())
498 break;
499
500 field = result->Fetch();
501 accRace = field[1].Get<uint8>();
502
503 if (!haveSameRace)
504 haveSameRace = createInfo->Race == accRace;
505
506 if (checkDeathKnightReqs)
507 {
508 uint8 acc_class = field[2].Get<uint8>();
509 if (acc_class == CLASS_DEATH_KNIGHT)
510 {
511 if (freeDeathKnightSlots > 0)
512 --freeDeathKnightSlots;
513
514 if (freeDeathKnightSlots == 0)
515 {
517 return;
518 }
519 }
520
521 if (!hasHeroicReqLevel)
522 {
523 uint8 acc_level = field[0].Get<uint8>();
524 if (acc_level >= heroicReqLevel)
525 hasHeroicReqLevel = true;
526 }
527 }
528 }
529 }
530
531 if (checkDeathKnightReqs && !hasHeroicReqLevel)
532 {
534 return;
535 }
536
537 // Check name uniqueness in the same step as saving to database
538 if (sCharacterCache->GetCharacterGuidByName(createInfo->Name))
539 {
541 return;
542 }
543
544 std::shared_ptr<Player> newChar(new Player(this), [](Player* ptr)
545 {
547 delete ptr;
548 });
549
550 newChar->GetMotionMaster()->Initialize();
551 if (!newChar->Create(sObjectMgr->GetGenerator<HighGuid::Player>().Generate(), createInfo.get()))
552 {
553 // Player not create (race/class/etc problem?)
555 return;
556 }
557
558 if ((haveSameRace && skipCinematics == 1) || skipCinematics == 2)
559 newChar->setCinematic(1); // not show intro
560
561 newChar->SetAtLoginFlag(AT_LOGIN_FIRST); // First login
562
563 CharacterDatabaseTransaction characterTransaction = CharacterDatabase.BeginTransaction();
564 LoginDatabaseTransaction trans = LoginDatabase.BeginTransaction();
565
566 // Player created, save it now
567 newChar->SaveToDB(characterTransaction, true, false);
568 createInfo->CharCount++;
569
571 stmt->SetData(0, createInfo->CharCount);
572 stmt->SetData(1, GetAccountId());
573 stmt->SetData(2, realm.Id.Realm);
574 trans->Append(stmt);
575
576 LoginDatabase.CommitTransaction(trans);
577
578 AddTransactionCallback(CharacterDatabase.AsyncCommitTransaction(characterTransaction)).AfterComplete([this, newChar = std::move(newChar)](bool success)
579 {
580 if (success)
581 {
582 LOG_INFO("entities.player.character", "Account: {} (IP: {}) Create Character: {} {}", GetAccountId(), GetRemoteAddress(), newChar->GetName(), newChar->GetGUID().ToString());
583 sScriptMgr->OnPlayerCreate(newChar.get());
584 sCharacterCache->AddCharacterCacheEntry(newChar->GetGUID(), GetAccountId(), newChar->GetName(), newChar->getGender(), newChar->getRace(), newChar->getClass(), newChar->getLevel());
586 }
587 else
589 });
590 };
591
592 if (allowTwoSideAccounts && !skipCinematics && createInfo->Class != CLASS_DEATH_KNIGHT)
593 {
594 finalizeCharacterCreation(PreparedQueryResult(nullptr));
595 return;
596 }
597
599 stmt->SetData(0, GetAccountId());
600 stmt->SetData(1, (skipCinematics == 1 || createInfo->Class == CLASS_DEATH_KNIGHT) ? 10 : 1);
601 queryCallback.WithPreparedCallback(std::move(finalizeCharacterCreation)).SetNextQuery(CharacterDatabase.AsyncQuery(stmt));
602 }));
603}
SQLTransaction< LoginDatabaseConnection > LoginDatabaseTransaction
std::shared_ptr< PreparedResultSet > PreparedQueryResult
@ CHAR_SEL_CHECK_NAME
@ CHAR_SEL_SUM_CHARS
@ CHAR_SEL_CHAR_CREATE_INFO
@ LOGIN_REP_REALM_CHARACTERS
Definition: LoginDatabase.h:63
@ LOGIN_SEL_SUM_REALM_CHARACTERS
Definition: LoginDatabase.h:64
DBCStorage< ChrRacesEntry > sChrRacesStore(ChrRacesEntryfmt)
DBCStorage< ChrClassesEntry > sChrClassesStore(ChrClassesEntryfmt)
@ AT_LOGIN_FIRST
Definition: Player.h:606
@ CONFIG_CHARACTER_CREATING_DISABLED_CLASSMASK
Definition: IWorld.h:222
@ CONFIG_CHARACTER_CREATING_DISABLED
Definition: IWorld.h:220
@ CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK
Definition: IWorld.h:221
@ CONFIG_CHARACTERS_PER_ACCOUNT
Definition: IWorld.h:223
@ CONFIG_HEROIC_CHARACTERS_PER_REALM
Definition: IWorld.h:226
@ CONFIG_CHARACTER_CREATING_MIN_LEVEL_FOR_HEROIC_CHARACTER
Definition: IWorld.h:227
@ CONFIG_SKIP_CINEMATICS
Definition: IWorld.h:228
@ CONFIG_CHARACTERS_PER_REALM
Definition: IWorld.h:224
@ CONFIG_ALLOW_TWO_SIDE_ACCOUNTS
Definition: IWorld.h:76
ResponseCodes
@ CHAR_CREATE_EXPANSION
@ CHAR_NAME_NO_NAME
@ CHAR_CREATE_DISABLED
@ CHAR_CREATE_LEVEL_REQUIREMENT
@ CHAR_CREATE_FAILED
@ CHAR_NAME_RESERVED
@ CHAR_CREATE_ERROR
@ CHAR_CREATE_NAME_IN_USE
@ CHAR_CREATE_SERVER_LIMIT
@ CHAR_CREATE_EXPANSION_CLASS
@ CHAR_CREATE_SUCCESS
@ CHAR_CREATE_PVP_TEAMS_VIOLATION
@ CHAR_CREATE_ACCOUNT_LIMIT
@ CHAR_CREATE_UNIQUE_CLASS_LIMIT
@ CHAR_NAME_SUCCESS
void SetNextQuery(QueryCallback &&next)
QueryCallback && WithPreparedCallback(std::function< void(PreparedQueryResult)> &&callback)
void AfterComplete(std::function< void(bool)> callback) &
Definition: Transaction.h:117
void CleanupsBeforeDelete(bool finalCleanup=true) override
Definition: Player.cpp:462
static uint8 CheckPlayerName(std::string_view name, bool create=false)
Definition: ObjectMgr.cpp:8129
uint8 Expansion() const
Definition: WorldSession.h:371
TransactionCallback & AddTransactionCallback(TransactionCallback &&callback)
void SendCharCreate(ResponseCodes result)
uint32 expansion
Definition: DBCStructure.h:698

◆ HandleCharCustomize()

void WorldSession::HandleCharCustomize ( WorldPacket recvData)

Definition at line 1615 of file CharacterHandler.cpp.

1616{
1617 std::shared_ptr<CharacterCustomizeInfo> customizeInfo = std::make_shared<CharacterCustomizeInfo>();
1618
1619 recvData >> customizeInfo->Guid;
1620
1621 if (!IsLegitCharacterForAccount(customizeInfo->Guid))
1622 {
1623 LOG_ERROR("entities.player.cheat", "Account {}, IP: {} tried to customise {}, but it does not belong to their account!",
1624 GetAccountId(), GetRemoteAddress(), customizeInfo->Guid.ToString());
1625 recvData.rfinish();
1626 KickPlayer("WorldSession::HandleCharCustomize Trying to customise character of another account");
1627 return;
1628 }
1629
1630 // pussywizard:
1631 if (ObjectAccessor::FindConnectedPlayer(customizeInfo->Guid) || sWorld->FindOfflineSessionForCharacterGUID(customizeInfo->Guid.GetCounter()))
1632 {
1633 recvData.rfinish();
1635 data << uint8(CHAR_CREATE_ERROR);
1636 SendPacket(&data);
1637 return;
1638 }
1639
1640 recvData >> customizeInfo->Name
1641 >> customizeInfo->Gender
1642 >> customizeInfo->Skin
1643 >> customizeInfo->HairColor
1644 >> customizeInfo->HairStyle
1645 >> customizeInfo->FacialHair
1646 >> customizeInfo->Face;
1647
1649 stmt->SetData(0, customizeInfo->Guid.GetCounter());
1650
1652 .WithPreparedCallback(std::bind(&WorldSession::HandleCharCustomizeCallback, this, customizeInfo, std::placeholders::_1)));
1653}
@ CHAR_SEL_CHAR_CUSTOMIZE_INFO
@ SMSG_CHAR_CUSTOMIZE
Definition: Opcodes.h:1170
void HandleCharCustomizeCallback(std::shared_ptr< CharacterCustomizeInfo > customizeInfo, PreparedQueryResult result)
bool IsLegitCharacterForAccount(ObjectGuid guid)

◆ HandleCharCustomizeCallback()

void WorldSession::HandleCharCustomizeCallback ( std::shared_ptr< CharacterCustomizeInfo customizeInfo,
PreparedQueryResult  result 
)

Customize

Name Change and update atLogin flags

Definition at line 1655 of file CharacterHandler.cpp.

1656{
1657 if (!result)
1658 {
1659 SendCharCustomize(CHAR_CREATE_ERROR, customizeInfo.get());
1660 return;
1661 }
1662
1663 // get the players old (at this moment current) race
1664 CharacterCacheEntry const* playerData = sCharacterCache->GetCharacterCacheByGuid(customizeInfo->Guid);
1665 if (!playerData)
1666 {
1667 SendCharCustomize(CHAR_CREATE_ERROR, customizeInfo.get());
1668 return;
1669 }
1670
1671 Field* fields = result->Fetch();
1672 std::string oldName = fields[0].Get<std::string>();
1673 //uint8 plrRace = fields[1].Get<uint8>();
1674 //uint8 plrClass = fields[2].Get<uint8>();
1675 //uint8 plrGender = fields[3].Get<uint8>();
1676 uint32 atLoginFlags = fields[4].Get<uint16>();
1677
1678 if (!(atLoginFlags & AT_LOGIN_CUSTOMIZE))
1679 {
1680 SendCharCustomize(CHAR_CREATE_ERROR, customizeInfo.get());
1681 return;
1682 }
1683
1684 atLoginFlags &= ~AT_LOGIN_CUSTOMIZE;
1685
1686 // prevent character rename to invalid name
1687 if (!normalizePlayerName(customizeInfo->Name))
1688 {
1689 SendCharCustomize(CHAR_NAME_NO_NAME, customizeInfo.get());
1690 return;
1691 }
1692
1693 ResponseCodes res = static_cast<ResponseCodes>(ObjectMgr::CheckPlayerName(customizeInfo->Name, true));
1694 if (res != CHAR_NAME_SUCCESS)
1695 {
1696 SendCharCustomize(res, customizeInfo.get());
1697 return;
1698 }
1699
1700 // check name limitations
1701 if (AccountMgr::IsPlayerAccount(GetSecurity()) && sObjectMgr->IsReservedName(customizeInfo->Name))
1702 {
1703 SendCharCustomize(CHAR_NAME_RESERVED, customizeInfo.get());
1704 return;
1705 }
1706
1707 // character with this name already exist
1708 if (ObjectGuid newguid = sCharacterCache->GetCharacterGuidByName(customizeInfo->Name))
1709 {
1710 if (newguid != customizeInfo->Guid)
1711 {
1712 SendCharCustomize(CHAR_CREATE_NAME_IN_USE, customizeInfo.get());
1713 return;
1714 }
1715 }
1716
1717 CharacterDatabasePreparedStatement* stmt = nullptr;
1718 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
1719
1720 ObjectGuid::LowType lowGuid = customizeInfo->Guid.GetCounter();
1721
1723 Player::Customize(customizeInfo.get(), trans);
1724
1726 {
1727 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_NAME_AT_LOGIN);
1728 stmt->SetData(0, customizeInfo->Name);
1729 stmt->SetData(1, atLoginFlags);
1730 stmt->SetData(2, lowGuid);
1731
1732 trans->Append(stmt);
1733
1734 if (sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED))
1735 {
1736 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_DECLINED_NAME);
1737 stmt->SetData(0, lowGuid);
1738
1739 trans->Append(stmt);
1740 }
1741 }
1742
1743 CharacterDatabase.CommitTransaction(trans);
1744
1745 sCharacterCache->UpdateCharacterData(customizeInfo->Guid, customizeInfo->Name, customizeInfo->Gender);
1746
1747 SendCharCustomize(RESPONSE_SUCCESS, customizeInfo.get());
1748
1749 LOG_INFO("entities.player.character", "Account: {} (IP: {}), Character[{}] ({}) Customized to: {}",
1750 GetAccountId(), GetRemoteAddress(), oldName, customizeInfo->Guid.ToString(), customizeInfo->Name);
1751}
@ CHAR_DEL_DECLINED_NAME
@ CHAR_UPD_CHAR_NAME_AT_LOGIN
@ AT_LOGIN_CUSTOMIZE
Definition: Player.h:604
@ CONFIG_DECLINED_NAMES_USED
Definition: IWorld.h:112
@ RESPONSE_SUCCESS
uint32 LowType
Definition: ObjectGuid.h:124
static void Customize(CharacterCustomizeInfo const *customizeInfo, CharacterDatabaseTransaction trans)
Definition: PlayerMisc.cpp:114
void SendCharCustomize(ResponseCodes result, CharacterCustomizeInfo const *customizeInfo)

◆ HandleCharDeleteOpcode()

void WorldSession::HandleCharDeleteOpcode ( WorldPacket recvPacket)

Definition at line 605 of file CharacterHandler.cpp.

606{
607 ObjectGuid guid;
608 recvData >> guid;
609
610 // Initiating
611 uint32 initAccountId = GetAccountId();
612
613 // can't delete loaded character
614 if (ObjectAccessor::FindConnectedPlayer(guid) || sWorld->FindOfflineSessionForCharacterGUID(guid.GetCounter()))
615 {
616 sScriptMgr->OnPlayerFailedDelete(guid, initAccountId);
617 return;
618 }
619
620 uint32 accountId = 0;
621 uint8 level = 0;
622 std::string name;
623
624 // is guild leader
625 if (sGuildMgr->GetGuildByLeader(guid))
626 {
627 sScriptMgr->OnPlayerFailedDelete(guid, initAccountId);
629 return;
630 }
631
632 // is arena team captain
633 if (sArenaTeamMgr->GetArenaTeamByCaptain(guid))
634 {
635 sScriptMgr->OnPlayerFailedDelete(guid, initAccountId);
637 return;
638 }
639
640 if (CharacterCacheEntry const* playerData = sCharacterCache->GetCharacterCacheByGuid(guid))
641 {
642 accountId = playerData->AccountId;
643 name = playerData->Name;
644 level = playerData->Level;
645 }
646
647 // prevent deleting other players' characters using cheating tools
648 if (accountId != initAccountId)
649 {
650 sScriptMgr->OnPlayerFailedDelete(guid, initAccountId);
651 return;
652 }
653
654 LOG_INFO("entities.player.character", "Account: {}, IP: {} deleted character: {}, {}, Level: {}", accountId, GetRemoteAddress(), name, guid.ToString(), level);
655
656 // To prevent hook failure, place hook before removing reference from DB
657 sScriptMgr->OnPlayerDelete(guid, initAccountId); // To prevent race conditioning, but as it also makes sense, we hand the accountId over for successful delete.
658 sCalendarMgr->RemoveAllPlayerEventsAndInvites(guid);
659 Player::DeleteFromDB(guid.GetCounter(), GetAccountId(), true, false);
660
661 sCharacterCache->DeleteCharacterCacheEntry(guid, name);
663}
@ CHAR_DELETE_SUCCESS
@ CHAR_DELETE_FAILED_GUILD_LEADER
@ CHAR_DELETE_FAILED_ARENA_CAPTAIN
static void DeleteFromDB(ObjectGuid::LowType lowGuid, uint32 accountId, bool updateRealmChars, bool deleteFinally)
Definition: Player.cpp:3906
void SendCharDelete(ResponseCodes result)

◆ HandleCharEnum()

void WorldSession::HandleCharEnum ( PreparedQueryResult  result)

Definition at line 222 of file CharacterHandler.cpp.

223{
224 WorldPacket data(SMSG_CHAR_ENUM, 100); // we guess size
225
226 uint8 num = 0;
227
228 data << num;
229
230 _legitCharacters.clear();
231 if (result)
232 {
233 do
234 {
235 ObjectGuid guid = ObjectGuid::Create<HighGuid::Player>((*result)[0].Get<uint32>());
236 LOG_DEBUG("network.opcode", "Loading char {} from account {}.", guid.ToString(), GetAccountId());
237 if (Player::BuildEnumData(result, &data))
238 {
239 _legitCharacters.insert(guid);
240 ++num;
241 }
242 } while (result->NextRow());
243 }
244
245 data.put<uint8>(0, num);
246
247 SendPacket(&data);
248}
@ SMSG_CHAR_ENUM
Definition: Opcodes.h:89
static bool BuildEnumData(PreparedQueryResult result, WorldPacket *data)
Definition: Player.cpp:1078
GuidSet _legitCharacters

◆ HandleCharEnumOpcode()

void WorldSession::HandleCharEnumOpcode ( WorldPacket recvPacket)

get all the data necessary for loading all characters (along with their pets) on the account

Definition at line 250 of file CharacterHandler.cpp.

251{
253
255
256 if (sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED))
257 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ENUM_DECLINED_NAME);
258 else
259 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ENUM);
260
262 stmt->SetData(1, GetAccountId());
263
264 _queryProcessor.AddCallback(CharacterDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&WorldSession::HandleCharEnum, this, std::placeholders::_1)));
265}
@ CHAR_SEL_ENUM
@ CHAR_SEL_ENUM_DECLINED_NAME
@ PET_SAVE_AS_CURRENT
Definition: PetDefines.h:42
void HandleCharEnum(PreparedQueryResult result)

◆ HandleCharFactionOrRaceChange()

void WorldSession::HandleCharFactionOrRaceChange ( WorldPacket recvData)

Definition at line 1906 of file CharacterHandler.cpp.

1907{
1908 std::shared_ptr<CharacterFactionChangeInfo> factionChangeInfo = std::make_shared<CharacterFactionChangeInfo>();
1909
1910 recvData >> factionChangeInfo->Guid;
1911
1912 if (!IsLegitCharacterForAccount(factionChangeInfo->Guid))
1913 {
1914 LOG_ERROR("entities.player.cheat", "Account {}, IP: {} tried to factionchange character {}, but it does not belong to their account!",
1915 GetAccountId(), GetRemoteAddress(), factionChangeInfo->Guid.ToString());
1916 recvData.rfinish();
1917 KickPlayer("WorldSession::HandleCharFactionOrRaceChange Trying to change faction of character of another account");
1918 return;
1919 }
1920
1921 recvData >> factionChangeInfo->Name
1922 >> factionChangeInfo->Gender
1923 >> factionChangeInfo->Skin
1924 >> factionChangeInfo->HairColor
1925 >> factionChangeInfo->HairStyle
1926 >> factionChangeInfo->FacialHair
1927 >> factionChangeInfo->Face
1928 >> factionChangeInfo->Race;
1929
1930 // pussywizard:
1931 if (ObjectAccessor::FindConnectedPlayer(factionChangeInfo->Guid) || sWorld->FindOfflineSessionForCharacterGUID(factionChangeInfo->Guid.GetCounter()))
1932 {
1933 SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
1934 return;
1935 }
1936
1937 factionChangeInfo->FactionChange = (recvData.GetOpcode() == CMSG_CHAR_FACTION_CHANGE);
1938
1940 stmt->SetData(0, factionChangeInfo->Guid.GetCounter());
1941
1943 .WithPreparedCallback(std::bind(&WorldSession::HandleCharFactionOrRaceChangeCallback, this, factionChangeInfo, std::placeholders::_1)));
1944}
@ CHAR_SEL_CHAR_RACE_OR_FACTION_CHANGE_INFOS
@ CMSG_CHAR_FACTION_CHANGE
Definition: Opcodes.h:1271
void HandleCharFactionOrRaceChangeCallback(std::shared_ptr< CharacterFactionChangeInfo > factionChangeInfo, PreparedQueryResult result)
void SendCharFactionChange(ResponseCodes result, CharacterFactionChangeInfo const *factionChangeInfo)

◆ HandleCharFactionOrRaceChangeCallback()

void WorldSession::HandleCharFactionOrRaceChangeCallback ( std::shared_ptr< CharacterFactionChangeInfo factionChangeInfo,
PreparedQueryResult  result 
)

Definition at line 1946 of file CharacterHandler.cpp.

1947{
1948 if (!result)
1949 {
1950 SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
1951 return;
1952 }
1953
1954 ObjectGuid::LowType lowGuid = factionChangeInfo->Guid.GetCounter();
1955
1956 // get the players old (at this moment current) race
1957 CharacterCacheEntry const* playerData = sCharacterCache->GetCharacterCacheByGuid(factionChangeInfo->Guid);
1958 if (!playerData)
1959 {
1960 SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
1961 return;
1962 }
1963
1964 uint8 oldRace = playerData->Race;
1965 uint8 playerClass = playerData->Class;
1966 uint8 level = playerData->Level;
1967
1968 if (!sObjectMgr->GetPlayerInfo(factionChangeInfo->Race, playerClass))
1969 {
1970 SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
1971 return;
1972 }
1973
1974 Field* fields = result->Fetch();
1975 uint32 atLoginFlags = fields[0].Get<uint16>();
1976 std::string knownTitlesStr = fields[1].Get<std::string>();
1977 uint32 money = fields[2].Get<uint32>();
1978
1979 uint32 usedLoginFlag = (factionChangeInfo->FactionChange ? AT_LOGIN_CHANGE_FACTION : AT_LOGIN_CHANGE_RACE);
1980 if (!(atLoginFlags & usedLoginFlag))
1981 {
1982 SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
1983 return;
1984 }
1985
1986 // xinef: add some safety checks
1987 if (factionChangeInfo->FactionChange)
1988 {
1989 // if player is in a guild
1990 if (playerData->GuildId && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD))
1991 {
1992 SendCharFactionChange(CHAR_CREATE_CHARACTER_IN_GUILD, factionChangeInfo.get());
1993 return;
1994 }
1995
1996 // is arena team captain
1997 if (sArenaTeamMgr->GetArenaTeamByCaptain(factionChangeInfo->Guid))
1998 {
2000 return;
2001 }
2002
2003 // check mailbox
2004 if (playerData->MailCount)
2005 {
2007 return;
2008 }
2009
2010 // check auctions, current packet is processed single-threaded way, so not a problem
2011 bool has_auctions = false;
2012
2013 for (uint8 i = 0; i < 2; ++i) // check both neutral and faction-specific AH
2014 {
2015 AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(i == 0 ? 0 : (((1 << (playerData->Race - 1)) & RACEMASK_ALLIANCE) ? 12 : 29));
2016
2017 for (auto const& [auID, Aentry] : auctionHouse->GetAuctions())
2018 {
2019 if (Aentry && (Aentry->owner == factionChangeInfo->Guid || Aentry->bidder == factionChangeInfo->Guid))
2020 {
2021 has_auctions = true;
2022 break;
2023 }
2024 }
2025
2026 if (has_auctions)
2027 break;
2028 }
2029
2030 if (has_auctions)
2031 {
2032 SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
2033 return;
2034 }
2035 }
2036
2037 TeamId newTeam = Player::TeamIdForRace(factionChangeInfo->Race);
2038 if (factionChangeInfo->FactionChange == (Player::TeamIdForRace(oldRace) == newTeam))
2039 {
2040 SendCharFactionChange(factionChangeInfo->FactionChange ? CHAR_CREATE_CHARACTER_SWAP_FACTION : CHAR_CREATE_CHARACTER_RACE_ONLY, factionChangeInfo.get());
2041 return;
2042 }
2043
2044 uint32 maxMoney = sWorld->getIntConfig(CONFIG_CHANGE_FACTION_MAX_MONEY);
2045 if (maxMoney && money > maxMoney)
2046 {
2048 return;
2049 }
2050
2051 // pussywizard: check titles here to prevent return while building queries
2052 const uint32 ktcount = KNOWN_TITLES_SIZE * 2;
2053 std::vector<std::string_view> tokens = Acore::Tokenize(knownTitlesStr, ' ', false);
2054
2055 if (factionChangeInfo->FactionChange && tokens.size() != ktcount)
2056 {
2057 SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
2058 return;
2059 }
2060
2062 {
2063 uint32 raceMaskDisabled = sWorld->getIntConfig(CONFIG_CHARACTER_CREATING_DISABLED_RACEMASK);
2064 if ((1 << (factionChangeInfo->Race - 1)) & raceMaskDisabled)
2065 {
2066 SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
2067 return;
2068 }
2069 }
2070
2071 // prevent character rename to invalid name
2072 if (!normalizePlayerName(factionChangeInfo->Name))
2073 {
2074 SendCharFactionChange(CHAR_NAME_NO_NAME, factionChangeInfo.get());
2075 return;
2076 }
2077
2078 ResponseCodes res = static_cast<ResponseCodes>(ObjectMgr::CheckPlayerName(factionChangeInfo->Name, true));
2079 if (res != CHAR_NAME_SUCCESS)
2080 {
2081 SendCharFactionChange(res, factionChangeInfo.get());
2082 return;
2083 }
2084
2085 // check name limitations
2086 if (AccountMgr::IsPlayerAccount(GetSecurity()) && sObjectMgr->IsReservedName(factionChangeInfo->Name))
2087 {
2088 SendCharFactionChange(CHAR_NAME_RESERVED, factionChangeInfo.get());
2089 return;
2090 }
2091
2092 // character with this name already exist
2093 if (ObjectGuid newguid = sCharacterCache->GetCharacterGuidByName(factionChangeInfo->Name))
2094 {
2095 if (newguid != factionChangeInfo->Guid)
2096 {
2097 SendCharFactionChange(CHAR_CREATE_NAME_IN_USE, factionChangeInfo.get());
2098 return;
2099 }
2100 }
2101
2102 CharacterDatabasePreparedStatement* stmt = nullptr;
2103 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
2104
2105 // resurrect the character in case he's dead
2106 Player::OfflineResurrect(factionChangeInfo->Guid, trans);
2107
2108 // Name Change and update atLogin flags
2109 {
2110 CharacterDatabase.EscapeString(factionChangeInfo->Name);
2111
2112 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_NAME_AT_LOGIN);
2113 stmt->SetData(0, factionChangeInfo->Name);
2114 stmt->SetData(1, uint16((atLoginFlags | AT_LOGIN_RESURRECT) & ~usedLoginFlag));
2115 stmt->SetData(2, lowGuid);
2116 trans->Append(stmt);
2117
2118 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_DECLINED_NAME);
2119 stmt->SetData(0, lowGuid);
2120 trans->Append(stmt);
2121 }
2122
2123 // Customize
2124 Player::Customize(factionChangeInfo.get(), trans);
2125
2126 // Race Change
2127 {
2128 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_RACE);
2129 stmt->SetData(0, factionChangeInfo->Race);
2130 stmt->SetData(1, lowGuid);
2131 trans->Append(stmt);
2132 }
2133
2134 LOG_INFO("entities.player.character", "Account: {} (IP: {}), Character [{}] (guid: {}) Changed Race/Faction to: {}",
2135 GetAccountId(), GetRemoteAddress(), playerData->Name, lowGuid, factionChangeInfo->Name);
2136
2137 // xinef: update global data
2138 sCharacterCache->UpdateCharacterData(factionChangeInfo->Guid, factionChangeInfo->Name, factionChangeInfo->Gender, factionChangeInfo->Race);
2139
2140 if (oldRace != factionChangeInfo->Race)
2141 {
2142 // Switch Languages
2143 // delete all languages first
2144 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SKILL_LANGUAGES);
2145 stmt->SetData(0, lowGuid);
2146 trans->Append(stmt);
2147
2148 // Now add them back
2149 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_SKILL_LANGUAGE);
2150 stmt->SetData(0, lowGuid);
2151
2152 // Faction specific languages
2153 if (newTeam == TEAM_HORDE)
2154 stmt->SetData(1, 109);
2155 else
2156 stmt->SetData(1, 98);
2157
2158 trans->Append(stmt);
2159
2160 // Race specific languages
2161 if (factionChangeInfo->Race != RACE_ORC && factionChangeInfo->Race != RACE_HUMAN)
2162 {
2163 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_SKILL_LANGUAGE);
2164 stmt->SetData(0, lowGuid);
2165
2166 switch (factionChangeInfo->Race)
2167 {
2168 case RACE_DWARF:
2169 stmt->SetData(1, 111);
2170 break;
2171 case RACE_DRAENEI:
2172 stmt->SetData(1, 759);
2173 break;
2174 case RACE_GNOME:
2175 stmt->SetData(1, 313);
2176 break;
2177 case RACE_NIGHTELF:
2178 stmt->SetData(1, 113);
2179 break;
2180 case RACE_UNDEAD_PLAYER:
2181 stmt->SetData(1, 673);
2182 break;
2183 case RACE_TAUREN:
2184 stmt->SetData(1, 115);
2185 break;
2186 case RACE_TROLL:
2187 stmt->SetData(1, 315);
2188 break;
2189 case RACE_BLOODELF:
2190 stmt->SetData(1, 137);
2191 break;
2192 }
2193
2194 trans->Append(stmt);
2195 }
2196
2197 if (factionChangeInfo->FactionChange)
2198 {
2199 {
2200 // Delete all Flypaths
2201 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_TAXI_PATH);
2202 stmt->SetData(0, lowGuid);
2203 trans->Append(stmt);
2204
2205 // Update Taxi path
2206 TaxiMask newTaxiMask;
2207 newTaxiMask.fill(0);
2208
2209 TaxiMask const& factionMask = newTeam == TEAM_HORDE ? sHordeTaxiNodesMask : sAllianceTaxiNodesMask;
2210 for (auto const& itr : sTaxiPathSetBySource)
2211 {
2212 auto FillTaxiMask = [&](uint8 field, uint32 mask)
2213 {
2214 if (playerClass == CLASS_DEATH_KNIGHT)
2215 {
2216 newTaxiMask[field] |= uint32(mask | (sDeathKnightTaxiNodesMask[field] & mask));
2217 }
2218 else
2219 {
2220 newTaxiMask[field] |= mask;
2221 }
2222 };
2223
2224 uint32 nodeId = itr.first;
2225 uint8 field = (uint8)((nodeId - 1) / 32);
2226 uint32 submask = 1 << ((nodeId - 1) % 32);
2227
2228 if ((factionMask[field] & submask) == 0)
2229 {
2230 FillTaxiMask(field, 0);
2231 continue;
2232 }
2233
2234 TaxiPathSetForSource const& taxiPaths = itr.second;
2235 if (taxiPaths.empty())
2236 {
2237 FillTaxiMask(field, 0);
2238 continue;
2239 }
2240
2241 TaxiPathEntry const* taxiPath = taxiPaths.begin()->second;
2242 if (!taxiPath)
2243 {
2244 FillTaxiMask(field, 0);
2245 continue;
2246 }
2247
2248 TaxiPathNodeList const& taxiNodePaths = sTaxiPathNodesByPath[taxiPath->ID];
2249 if (taxiNodePaths.empty())
2250 {
2251 FillTaxiMask(field, 0);
2252 continue;
2253 }
2254
2255 TaxiPathNodeEntry const* pathNode = taxiNodePaths.front();
2256 if (!pathNode)
2257 {
2258 FillTaxiMask(field, 0);
2259 continue;
2260 }
2261
2262 AreaTableEntry const* zone = sAreaTableStore.LookupEntry(sMapMgr->GetZoneId(PHASEMASK_NORMAL, pathNode->mapid, pathNode->x, pathNode->y, pathNode->z));
2263 if (!zone)
2264 {
2265 FillTaxiMask(field, 0);
2266 continue;
2267 }
2268
2270 if (!lfgDungeon)
2271 {
2272 FillTaxiMask(field, 0);
2273 continue;
2274 }
2275
2276 // Get level from LFGDungeonEntry because the one from AreaTableEntry is not valid
2277 // If area level is too big, do not add new taxi
2278 if (lfgDungeon->minlevel > level)
2279 {
2280 FillTaxiMask(field, 0);
2281 continue;
2282 }
2283
2284 FillTaxiMask(field, submask);
2285 }
2286
2287 std::ostringstream taximaskstream;
2288 for (uint8 i = 0; i < TaxiMaskSize; ++i)
2289 taximaskstream << uint32(newTaxiMask[i]) << ' ';
2290
2291 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_TAXIMASK);
2292 stmt->SetData(0, taximaskstream.str());
2293 stmt->SetData(1, lowGuid);
2294 trans->Append(stmt);
2295 }
2296
2297 // Reset guild
2299 {
2300 if (uint32 guildId = playerData->GuildId)
2301 if (Guild* guild = sGuildMgr->GetGuildById(guildId))
2302 guild->DeleteMember(factionChangeInfo->Guid, false, false, true);
2303 }
2304
2305 if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_ADD_FRIEND))
2306 {
2307 // Delete Friend List
2308 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SOCIAL_BY_GUID);
2309 stmt->SetData(0, lowGuid);
2310 trans->Append(stmt);
2311
2312 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SOCIAL_BY_FRIEND);
2313 stmt->SetData(0, lowGuid);
2314 trans->Append(stmt);
2315 }
2316
2317 // Leave Arena Teams
2318 Player::LeaveAllArenaTeams(factionChangeInfo->Guid);
2319
2320 // Reset homebind and position
2321 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PLAYER_HOMEBIND);
2322 stmt->SetData(0, lowGuid);
2323 trans->Append(stmt);
2324
2325 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PLAYER_HOMEBIND);
2326 stmt->SetData(0, lowGuid);
2327
2328 WorldLocation loc;
2329 uint16 zoneId = 0;
2330
2331 if (newTeam == TEAM_ALLIANCE)
2332 {
2333 loc.WorldRelocate(0, -8867.68f, 673.373f, 97.9034f, 0.0f);
2334 zoneId = 1519;
2335 }
2336 else
2337 {
2338 loc.WorldRelocate(1, 1633.33f, -4439.11f, 15.7588f, 0.0f);
2339 zoneId = 1637;
2340 }
2341
2342 stmt->SetData(1, loc.GetMapId());
2343 stmt->SetData(2, zoneId);
2344 stmt->SetData(3, loc.GetPositionX());
2345 stmt->SetData(4, loc.GetPositionY());
2346 stmt->SetData(5, loc.GetPositionZ());
2347 stmt->SetData(6, loc.GetOrientation());
2348 trans->Append(stmt);
2349
2350 Player::SavePositionInDB(loc, zoneId, factionChangeInfo->Guid, trans);
2351
2352 // Achievement conversion
2353 for (auto const& [achiev_alliance, achiev_horde] : sObjectMgr->FactionChangeAchievements)
2354 {
2356 stmt->SetData(0, uint16(newTeam == TEAM_ALLIANCE ? achiev_alliance : achiev_horde));
2357 stmt->SetData(1, lowGuid);
2358 trans->Append(stmt);
2359
2360 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_ACHIEVEMENT);
2361 stmt->SetData(0, uint16(newTeam == TEAM_ALLIANCE ? achiev_alliance : achiev_horde));
2362 stmt->SetData(1, uint16(newTeam == TEAM_ALLIANCE ? achiev_horde : achiev_alliance));
2363 stmt->SetData(2, lowGuid);
2364 trans->Append(stmt);
2365 }
2366
2367 // Item conversion
2368 for (auto const& [item_alliance, item_horde] : sObjectMgr->FactionChangeItems)
2369 {
2370 uint32 new_entry = (newTeam == TEAM_ALLIANCE ? item_alliance : item_horde);
2371 uint32 old_entry = (newTeam == TEAM_ALLIANCE ? item_horde : item_alliance);
2372
2373 if (old_entry == 45978 /*Solid Gold Coin*/ || old_entry == 2589 /*Linen Cloth*/ || old_entry == 5976 /*Guild Tabard*/)
2374 continue;
2375
2376 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_INVENTORY_FACTION_CHANGE);
2377 stmt->SetData(0, new_entry);
2378 stmt->SetData(1, old_entry);
2379 stmt->SetData(2, lowGuid);
2380 trans->Append(stmt);
2381 }
2382
2383 // Delete all current quests
2384 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_QUESTSTATUS);
2385 stmt->SetData(0, lowGuid);
2386 trans->Append(stmt);
2387
2388 // Quest conversion
2389 for (auto const& [quest_alliance, quest_horde] : sObjectMgr->FactionChangeQuests)
2390 {
2392 stmt->SetData(0, lowGuid);
2393 stmt->SetData(1, (newTeam == TEAM_ALLIANCE ? quest_alliance : quest_horde));
2394 trans->Append(stmt);
2395
2397 stmt->SetData(0, (newTeam == TEAM_ALLIANCE ? quest_alliance : quest_horde));
2398 stmt->SetData(1, (newTeam == TEAM_ALLIANCE ? quest_horde : quest_alliance));
2399 stmt->SetData(2, lowGuid);
2400 trans->Append(stmt);
2401 }
2402
2403 // Mark all rewarded quests as "active" (will count for completed quests achievements)
2405 stmt->SetData(0, lowGuid);
2406 trans->Append(stmt);
2407
2408 // Disable all old-faction specific quests
2409 for (auto const& [questID, quest] : sObjectMgr->GetQuestTemplates())
2410 {
2411 uint32 newRaceMask = (newTeam == TEAM_ALLIANCE) ? RACEMASK_ALLIANCE : RACEMASK_HORDE;
2412
2413 if (quest->GetAllowableRaces() && !(quest->GetAllowableRaces() & newRaceMask))
2414 {
2416 stmt->SetData(0, quest->GetQuestId());
2417 stmt->SetData(1, lowGuid);
2418 trans->Append(stmt);
2419 }
2420 }
2421
2422 // Spell conversion
2423 for (auto const& [spell_alliance, spell_horde] : sObjectMgr->FactionChangeSpells)
2424 {
2425 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SPELL_BY_SPELL);
2426 stmt->SetData(0, lowGuid);
2427 stmt->SetData(1, (newTeam == TEAM_ALLIANCE ? spell_alliance : spell_horde));
2428 trans->Append(stmt);
2429
2430 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_SPELL_FACTION_CHANGE);
2431 stmt->SetData(0, (newTeam == TEAM_ALLIANCE ? spell_alliance : spell_horde));
2432 stmt->SetData(1, (newTeam == TEAM_ALLIANCE ? spell_horde : spell_alliance));
2433 stmt->SetData(2, lowGuid);
2434 trans->Append(stmt);
2435 }
2436
2437 // Reputation conversion
2438 for (auto const& [reputation_alliance, reputation_horde] : sObjectMgr->FactionChangeReputation)
2439 {
2440 uint32 newReputation = (newTeam == TEAM_ALLIANCE) ? reputation_alliance : reputation_horde;
2441 uint32 oldReputation = (newTeam == TEAM_ALLIANCE) ? reputation_horde : reputation_alliance;
2442
2443 // select old standing set in db
2444 stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_REP_BY_FACTION);
2445 stmt->SetData(0, oldReputation);
2446 stmt->SetData(1, lowGuid);
2447
2448 PreparedQueryResult result = CharacterDatabase.Query(stmt);
2449 if (!result)
2450 continue;
2451
2452 fields = result->Fetch();
2453 int32 oldDBRep = fields[0].Get<int32>();
2454 FactionEntry const* factionEntry = sFactionStore.LookupEntry(oldReputation);
2455
2456 // old base reputation
2457 int32 oldBaseRep = sObjectMgr->GetBaseReputationOf(factionEntry, oldRace, playerClass);
2458
2459 // new base reputation
2460 int32 newBaseRep = sObjectMgr->GetBaseReputationOf(sFactionStore.LookupEntry(newReputation), factionChangeInfo->Race, playerClass);
2461
2462 // final reputation shouldnt change
2463 int32 FinalRep = oldDBRep + oldBaseRep;
2464 int32 newDBRep = FinalRep - newBaseRep;
2465
2466 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_REP_BY_FACTION);
2467 stmt->SetData(0, newReputation);
2468 stmt->SetData(1, lowGuid);
2469 trans->Append(stmt);
2470
2471 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_REP_FACTION_CHANGE);
2472 stmt->SetData(0, uint16(newReputation));
2473 stmt->SetData(1, newDBRep);
2474 stmt->SetData(2, uint16(oldReputation));
2475 stmt->SetData(3, lowGuid);
2476 trans->Append(stmt);
2477 }
2478
2479 // Title conversion
2480 if (!knownTitlesStr.empty())
2481 {
2482 std::array<uint32, KNOWN_TITLES_SIZE * 2> knownTitles;
2483
2484 for (uint32 index = 0; index < knownTitles.size(); ++index)
2485 {
2486 Optional<uint32> thisMask;
2487 if (index < tokens.size())
2488 thisMask = Acore::StringTo<uint32>(tokens[index]);
2489
2490 if (thisMask)
2491 knownTitles[index] = *thisMask;
2492 else
2493 {
2494 LOG_WARN("entities.player", "{} has invalid title data '{}' at index {} - skipped, this may result in titles being lost",
2495 GetPlayerInfo(), (index < tokens.size()) ? std::string(tokens[index]) : "<none>", index);
2496
2497 knownTitles[index] = 0;
2498 }
2499 }
2500
2501 for (auto const& [title_alliance, title_horde] : sObjectMgr->FactionChangeTitles)
2502 {
2503 CharTitlesEntry const* atitleInfo = sCharTitlesStore.LookupEntry(title_alliance);
2504 CharTitlesEntry const* htitleInfo = sCharTitlesStore.LookupEntry(title_horde);
2505
2506 // new team
2507 if (newTeam == TEAM_ALLIANCE)
2508 {
2509 uint32 bitIndex = htitleInfo->bit_index;
2510 uint32 index = bitIndex / 32;
2511 uint32 old_flag = 1 << (bitIndex % 32);
2512 uint32 new_flag = 1 << (atitleInfo->bit_index % 32);
2513
2514 if (knownTitles[index] & old_flag)
2515 {
2516 knownTitles[index] &= ~old_flag;
2517 // use index of the new title
2518 knownTitles[atitleInfo->bit_index / 32] |= new_flag;
2519 }
2520 }
2521 else
2522 {
2523 uint32 bitIndex = atitleInfo->bit_index;
2524 uint32 index = bitIndex / 32;
2525 uint32 old_flag = 1 << (bitIndex % 32);
2526 uint32 new_flag = 1 << (htitleInfo->bit_index % 32);
2527
2528 if (knownTitles[index] & old_flag)
2529 {
2530 knownTitles[index] &= ~old_flag;
2531 // use index of the new title
2532 knownTitles[htitleInfo->bit_index / 32] |= new_flag;
2533 }
2534 }
2535
2536 std::ostringstream ss;
2537 for (uint32 mask : knownTitles)
2538 ss << mask << ' ';
2539
2540 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_TITLES_FACTION_CHANGE);
2541 stmt->SetData(0, ss.str().c_str());
2542 stmt->SetData(1, lowGuid);
2543 trans->Append(stmt);
2544
2545 // unset any currently chosen title
2546 stmt = CharacterDatabase.GetPreparedStatement(CHAR_RES_CHAR_TITLES_FACTION_CHANGE);
2547 stmt->SetData(0, lowGuid);
2548 trans->Append(stmt);
2549 }
2550 }
2551 }
2552 }
2553
2554 // Re-check all achievement criterias
2555 stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG);
2557 stmt->SetData(1, lowGuid);
2558 trans->Append(stmt);
2559
2560 CharacterDatabase.CommitTransaction(trans);
2561
2562 LOG_DEBUG("entities.player", "{} (IP: {}) changed race from {} to {}", GetPlayerInfo(), GetRemoteAddress(), oldRace, factionChangeInfo->Race);
2563
2564 SendCharFactionChange(RESPONSE_SUCCESS, factionChangeInfo.get());
2565}
#define LOG_WARN(filterType__,...)
Definition: Log.h:163
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition: Optional.h:24
@ CHAR_DEL_CHAR_SOCIAL_BY_FRIEND
@ CHAR_UPD_CHAR_INVENTORY_FACTION_CHANGE
@ CHAR_DEL_CHAR_QUESTSTATUS_REWARDED_BY_QUEST
@ CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_FACTION_CHANGE
@ CHAR_DEL_CHAR_SKILL_LANGUAGES
@ CHAR_UPD_CHAR_ACHIEVEMENT
@ CHAR_DEL_CHAR_DECLINED_NAME
@ CHAR_INS_PLAYER_HOMEBIND
@ CHAR_INS_CHAR_SKILL_LANGUAGE
@ CHAR_UPD_CHAR_SPELL_FACTION_CHANGE
@ CHAR_UPD_CHAR_TAXI_PATH
@ CHAR_UPD_CHAR_TAXIMASK
@ CHAR_DEL_PLAYER_HOMEBIND
@ CHAR_SEL_CHAR_REP_BY_FACTION
@ CHAR_DEL_CHAR_SPELL_BY_SPELL
@ CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE_BY_QUEST
@ CHAR_DEL_CHAR_ACHIEVEMENT_BY_ACHIEVEMENT
@ CHAR_DEL_CHAR_QUESTSTATUS
@ CHAR_UPD_CHAR_REP_FACTION_CHANGE
@ CHAR_UPD_CHAR_RACE
@ CHAR_UPD_CHAR_TITLES_FACTION_CHANGE
@ CHAR_DEL_CHAR_REP_BY_FACTION
@ CHAR_UPD_ADD_AT_LOGIN_FLAG
@ CHAR_RES_CHAR_TITLES_FACTION_CHANGE
@ CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE
@ CHAR_DEL_CHAR_SOCIAL_BY_GUID
DBCStorage< CharTitlesEntry > sCharTitlesStore(CharTitlesEntryfmt)
DBCStorage< FactionEntry > sFactionStore(FactionEntryfmt)
TaxiMask sAllianceTaxiNodesMask
Definition: DBCStores.cpp:174
LFGDungeonEntry const * GetZoneLFGDungeonEntry(std::string const &zoneName, LocaleConstant locale)
Definition: DBCStores.cpp:849
TaxiPathSetBySource sTaxiPathSetBySource
Definition: DBCStores.cpp:178
TaxiPathNodesByPath sTaxiPathNodesByPath
Definition: DBCStores.cpp:182
TaxiMask sDeathKnightTaxiNodesMask
Definition: DBCStores.cpp:175
DBCStorage< AreaTableEntry > sAreaTableStore(AreaTableEntryfmt)
TaxiMask sHordeTaxiNodesMask
Definition: DBCStores.cpp:173
@ PHASEMASK_NORMAL
Definition: Object.h:56
#define KNOWN_TITLES_SIZE
Definition: Player.h:554
@ AT_LOGIN_RESURRECT
Definition: Player.h:612
@ AT_LOGIN_CHANGE_RACE
Definition: Player.h:608
@ AT_LOGIN_CHECK_ACHIEVS
Definition: Player.h:611
@ AT_LOGIN_CHANGE_FACTION
Definition: Player.h:607
@ CONFIG_CHANGE_FACTION_MAX_MONEY
Definition: IWorld.h:408
static constexpr size_t TaxiMaskSize
std::array< uint32, TaxiMaskSize > TaxiMask
std::vector< TaxiPathNodeEntry const * > TaxiPathNodeList
std::map< uint32, TaxiPathEntry const * > TaxiPathSetForSource
@ CHAR_CREATE_CHARACTER_IN_GUILD
@ CHAR_CREATE_CHARACTER_DELETE_MAIL
@ CHAR_CREATE_CHARACTER_GOLD_LIMIT
@ CHAR_CREATE_CHARACTER_ARENA_LEADER
@ CHAR_CREATE_CHARACTER_SWAP_FACTION
@ CHAR_CREATE_CHARACTER_RACE_ONLY
#define RACEMASK_HORDE
@ RACE_TROLL
Definition: SharedDefines.h:77
@ RACE_UNDEAD_PLAYER
Definition: SharedDefines.h:74
@ RACE_ORC
Definition: SharedDefines.h:71
@ RACE_DRAENEI
Definition: SharedDefines.h:80
@ RACE_NIGHTELF
Definition: SharedDefines.h:73
@ RACE_BLOODELF
Definition: SharedDefines.h:79
@ RACE_DWARF
Definition: SharedDefines.h:72
@ RACE_GNOME
Definition: SharedDefines.h:76
@ RACE_HUMAN
Definition: SharedDefines.h:70
@ RACE_TAUREN
Definition: SharedDefines.h:75
#define RACEMASK_ALLIANCE
std::vector< std::string_view > Tokenize(std::string_view str, char sep, bool keepEmpty)
Definition: Tokenize.cpp:20
AuctionEntryMap const & GetAuctions()
ObjectGuid::LowType GuildId
float GetPositionZ() const
Definition: Position.h:119
float GetOrientation() const
Definition: Position.h:120
void WorldRelocate(const WorldLocation &loc)
Definition: Position.h:259
static void OfflineResurrect(ObjectGuid const guid, CharacterDatabaseTransaction trans)
Definition: Player.cpp:4467
static void LeaveAllArenaTeams(ObjectGuid guid)
Definition: Player.cpp:9906
static void SavePositionInDB(uint32 mapid, float x, float y, float z, float o, uint32 zone, ObjectGuid guid)
Definition: PlayerMisc.cpp:84
char const * area_name[16]
Definition: DBCStructure.h:527

◆ HandleCharRenameCallBack()

void WorldSession::HandleCharRenameCallBack ( std::shared_ptr< CharacterRenameInfo renameInfo,
PreparedQueryResult  result 
)

Definition at line 1372 of file CharacterHandler.cpp.

1373{
1374 if (!result)
1375 {
1376 SendCharRename(CHAR_CREATE_ERROR, renameInfo.get());
1377 return;
1378 }
1379
1380 Field* fields = result->Fetch();
1381
1382 ObjectGuid::LowType guidLow = fields[0].Get<uint32>();
1383 std::string oldName = fields[1].Get<std::string>();
1384 uint16 atLoginFlags = fields[2].Get<uint16>();
1385
1386 if (!(atLoginFlags & AT_LOGIN_RENAME))
1387 {
1388 SendCharRename(CHAR_CREATE_ERROR, renameInfo.get());
1389 return;
1390 }
1391
1392 atLoginFlags &= ~AT_LOGIN_RENAME;
1393
1394 // pussywizard:
1395 if (ObjectAccessor::FindConnectedPlayer(ObjectGuid::Create<HighGuid::Player>(guidLow)) || sWorld->FindOfflineSessionForCharacterGUID(guidLow))
1396 {
1397 SendCharRename(CHAR_CREATE_ERROR, renameInfo.get());
1398 return;
1399 }
1400
1401 // Update name and at_login flag in the db
1403 stmt->SetData(0, renameInfo->Name);
1404 stmt->SetData(1, atLoginFlags);
1405 stmt->SetData(2, guidLow);
1406 CharacterDatabase.Execute(stmt);
1407
1408 // Removed declined name from db
1409 if (sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED))
1410 {
1411 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_DECLINED_NAME);
1412 stmt->SetData(0, guidLow);
1413 CharacterDatabase.Execute(stmt);
1414 }
1415
1416 LOG_INFO("entities.player.character", "Account: {} (IP: {}), Character [{}] (guid: {}) Changed name to: {}", GetAccountId(), GetRemoteAddress(), oldName, guidLow, renameInfo->Name);
1417
1418 SendCharRename(RESPONSE_SUCCESS, renameInfo.get());
1419
1420 // xinef: update global data
1421 sCharacterCache->UpdateCharacterData(renameInfo->Guid, renameInfo->Name);
1422}
@ AT_LOGIN_RENAME
Definition: Player.h:601
void SendCharRename(ResponseCodes result, CharacterRenameInfo const *renameInfo)

◆ HandleCharRenameOpcode()

void WorldSession::HandleCharRenameOpcode ( WorldPacket recvData)

Definition at line 1332 of file CharacterHandler.cpp.

1333{
1334 std::shared_ptr<CharacterRenameInfo> renameInfo = std::make_shared<CharacterRenameInfo>();
1335
1336 recvData >> renameInfo->Guid
1337 >> renameInfo->Name;
1338
1339 // prevent character rename to invalid name
1340 if (!normalizePlayerName(renameInfo->Name))
1341 {
1342 SendCharRename(CHAR_NAME_NO_NAME, renameInfo.get());
1343 return;
1344 }
1345
1346 uint8 res = ObjectMgr::CheckPlayerName(renameInfo->Name, true);
1347 if (res != CHAR_NAME_SUCCESS)
1348 {
1349 SendCharRename(ResponseCodes(res), renameInfo.get());
1350 return;
1351 }
1352
1353 // check name limitations
1354 if (AccountMgr::IsPlayerAccount(GetSecurity()) && sObjectMgr->IsReservedName(renameInfo->Name))
1355 {
1356 SendCharRename(CHAR_NAME_RESERVED, renameInfo.get());
1357 return;
1358 }
1359
1360 // Ensure that the character belongs to the current account, that rename at login is enabled
1361 // and that there is no character with the desired new name
1363
1364 stmt->SetData(0, renameInfo->Guid.GetCounter());
1365 stmt->SetData(1, GetAccountId());
1366 stmt->SetData(2, renameInfo->Name);
1367
1369 .WithPreparedCallback(std::bind(&WorldSession::HandleCharRenameCallBack, this, renameInfo, std::placeholders::_1)));
1370}
@ CHAR_SEL_FREE_NAME
void HandleCharRenameCallBack(std::shared_ptr< CharacterRenameInfo > renameInfo, PreparedQueryResult result)

◆ HandleChatIgnoredOpcode()

void WorldSession::HandleChatIgnoredOpcode ( WorldPacket recvPacket)

Definition at line 786 of file ChatHandler.cpp.

787{
788 ObjectGuid iguid;
789 uint8 unk;
790
791 recvData >> iguid;
792 recvData >> unk; // probably related to spam reporting
793
795 if (!player)
796 return;
797
798 WorldPacket data;
800 player->GetSession()->SendPacket(&data);
801}
@ CHAT_MSG_IGNORED
@ LANG_UNIVERSAL
static size_t BuildChatPacket(WorldPacket &data, ChatMsg chatType, Language language, ObjectGuid senderGUID, ObjectGuid receiverGUID, std::string_view message, uint8 chatTag, std::string const &senderName="", std::string const &receiverName="", uint32 achievementId=0, bool gmMessage=false, std::string const &channelName="")
Definition: Chat.cpp:192

◆ HandleClearChannelWatch()

void WorldSession::HandleClearChannelWatch ( WorldPacket recvPacket)

Definition at line 323 of file ChannelHandler.cpp.

324{
325 std::string channelName;
326 recvPacket >> channelName;
327
328 if (channelName.empty())
329 return;
330
332 if (Channel* channel = cMgr->GetChannel(channelName, nullptr, false))
333 channel->RemoveWatching(GetPlayer());
334}

◆ HandleClearTradeItemOpcode()

void WorldSession::HandleClearTradeItemOpcode ( WorldPacket recvPacket)

Definition at line 712 of file TradeHandler.cpp.

713{
714 uint8 tradeSlot;
715 recvPacket >> tradeSlot;
716
717 TradeData* my_trade = _player->m_trade;
718 if (!my_trade)
719 return;
720
721 // invalid slot number
722 if (tradeSlot >= TRADE_SLOT_COUNT)
723 return;
724
725 my_trade->SetItem(TradeSlots(tradeSlot), nullptr);
726}
@ TRADE_SLOT_COUNT
Definition: TradeData.h:29
void SetItem(TradeSlots slot, Item *item)
Definition: TradeData.cpp:54

◆ HandleClientCastFlags()

void WorldSession::HandleClientCastFlags ( WorldPacket recvPacket,
uint8  castFlags,
SpellCastTargets targets 
)

Definition at line 36 of file SpellHandler.cpp.

37{
38 // some spell cast packet including more data (for projectiles?)
39 if (castFlags & 0x02)
40 {
41 // not sure about these two
42 float elevation, speed;
43 recvPacket >> elevation;
44 recvPacket >> speed;
45
46 targets.SetElevation(elevation);
47 targets.SetSpeed(speed);
48
49 uint8 hasMovementData;
50 recvPacket >> hasMovementData;
51 if (hasMovementData)
52 {
53 recvPacket.SetOpcode(recvPacket.read<uint32>());
54 HandleMovementOpcodes(recvPacket);
55 }
56 }
57}
void SetOpcode(uint16 opcode)
Definition: WorldPacket.h:77
void HandleMovementOpcodes(WorldPacket &recvPacket)
void SetSpeed(float speed)
Definition: Spell.h:171
void SetElevation(float elevation)
Definition: Spell.h:169

◆ HandleComplainOpcode()

void WorldSession::HandleComplainOpcode ( WorldPacket recvData)

Definition at line 1179 of file MiscHandler.cpp.

1180{
1181 LOG_DEBUG("network", "WORLD: CMSG_COMPLAIN");
1182
1183 uint8 spam_type; // 0 - mail, 1 - chat
1184 ObjectGuid spammer_guid;
1185 uint32 unk1 = 0;
1186 uint32 unk2 = 0;
1187 uint32 unk3 = 0;
1188 uint32 unk4 = 0;
1189 std::string description = "";
1190 recv_data >> spam_type; // unk 0x01 const, may be spam type (mail/chat)
1191 recv_data >> spammer_guid; // player guid
1192 switch (spam_type)
1193 {
1194 case 0:
1195 recv_data >> unk1; // const 0
1196 recv_data >> unk2; // probably mail id
1197 recv_data >> unk3; // const 0
1198 break;
1199 case 1:
1200 recv_data >> unk1; // probably language
1201 recv_data >> unk2; // message type?
1202 recv_data >> unk3; // probably channel id
1203 recv_data >> unk4; // unk random value
1204 recv_data >> description; // spam description string (messagetype, channel name, player name, message)
1205 break;
1206 }
1207
1208 // NOTE: all chat messages from this spammer automatically ignored by spam reporter until logout in case chat spam.
1209 // if it's mail spam - ALL mails from this spammer automatically removed by client
1210
1211 // Complaint Received message
1213 data << uint8(0);
1214 SendPacket(&data);
1215
1216 LOG_DEBUG("network", "REPORT SPAM: type {}, {}, unk1 {}, unk2 {}, unk3 {}, unk4 {}, message {}",
1217 spam_type, spammer_guid.ToString(), unk1, unk2, unk3, unk4, description);
1218}
@ SMSG_COMPLAIN_RESULT
Definition: Opcodes.h:998

◆ HandleCompleteCinematic()

void WorldSession::HandleCompleteCinematic ( WorldPacket recvPacket)

Definition at line 980 of file MiscHandler.cpp.

981{
982{
983 LOG_DEBUG("network", "WORLD: Received CMSG_COMPLETE_CINEMATIC");
984}
985 // If player has sight bound to visual waypoint NPC we should remove it
987}
void EndCinematic()
CinematicMgr * GetCinematicMgr() const
Definition: Player.h:1347

◆ HandleContactListOpcode()

void WorldSession::HandleContactListOpcode ( WorldPacket recvPacket)

Definition at line 29 of file Socialhandler.cpp.

30{
31 uint32 flags;
32 recv_data >> flags;
33
34 LOG_DEBUG("network", "WORLD: Received CMSG_CONTACT_LIST - Unk: {}", flags);
35
37}
void SendSocialList(Player *player, uint32 flags)
Definition: SocialMgr.cpp:124

◆ HandleCorpseMapPositionQuery()

void WorldSession::HandleCorpseMapPositionQuery ( WorldPacket recvPacket)

Definition at line 397 of file QueryHandler.cpp.

398{
399 LOG_DEBUG("network", "WORLD: Recv CMSG_CORPSE_MAP_POSITION_QUERY");
400
401 uint32 unk;
402 recvData >> unk;
403
405 data << float(0);
406 data << float(0);
407 data << float(0);
408 data << float(0);
409 SendPacket(&data);
410}
@ SMSG_CORPSE_MAP_POSITION_QUERY_RESPONSE
Definition: Opcodes.h:1237

◆ HandleCorpseQueryOpcode()

void WorldSession::HandleCorpseQueryOpcode ( WorldPacket recvPacket)

Definition at line 220 of file QueryHandler.cpp.

221{
222 LOG_DEBUG("network", "WORLD: Received MSG_CORPSE_QUERY");
223
224 if (!_player->HasCorpse())
225 {
227 data << uint8(0); // corpse not found
228 SendPacket(&data);
229 return;
230 }
231
232 WorldLocation corpseLocation = _player->GetCorpseLocation();
233 uint32 corpseMapID = corpseLocation.GetMapId();
234 uint32 mapID = corpseLocation.GetMapId();
235 float x = corpseLocation.GetPositionX();
236 float y = corpseLocation.GetPositionY();
237 float z = corpseLocation.GetPositionZ();
238
239 // if corpse at different map
240 if (mapID != _player->GetMapId())
241 {
242 // search entrance map for proper show entrance
243 if (MapEntry const* corpseMapEntry = sMapStore.LookupEntry(mapID))
244 {
245 if (corpseMapEntry->IsDungeon() && corpseMapEntry->entrance_map >= 0)
246 {
247 // if corpse map have entrance
248 if (Map const* entranceMap = sMapMgr->CreateBaseMap(corpseMapEntry->entrance_map))
249 {
250 mapID = corpseMapEntry->entrance_map;
251 x = corpseMapEntry->entrance_x;
252 y = corpseMapEntry->entrance_y;
253 z = entranceMap->GetHeight(GetPlayer()->GetPhaseMask(), x, y, MAX_HEIGHT);
254 }
255 }
256 }
257 }
258
259 WorldPacket data(MSG_CORPSE_QUERY, 1 + (6 * 4));
260 data << uint8(1); // corpse found
261 data << int32(mapID);
262 data << float(x);
263 data << float(y);
264 data << float(z);
265 data << int32(corpseMapID);
266 data << uint32(0); // unknown
267 SendPacket(&data);
268}
#define MAX_HEIGHT
Definition: Map.h:163
@ MSG_CORPSE_QUERY
Definition: Opcodes.h:564
Definition: Map.h:312

◆ HandleCreatureQueryOpcode()

void WorldSession::HandleCreatureQueryOpcode ( WorldPacket recvPacket)

Only static data is sent in this packet !!!

Definition at line 94 of file QueryHandler.cpp.

95{
96 uint32 entry;
97 recvData >> entry;
98 ObjectGuid guid;
99 recvData >> guid;
100
101 CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(entry);
102 if (ci)
103 {
104 std::string Name, Title;
105 Name = ci->Name;
106 Title = ci->SubName;
107
109 if (loc_idx >= 0)
110 {
111 if (CreatureLocale const* cl = sObjectMgr->GetCreatureLocale(entry))
112 {
113 ObjectMgr::GetLocaleString(cl->Name, loc_idx, Name);
114 ObjectMgr::GetLocaleString(cl->Title, loc_idx, Title);
115 }
116 }
117 // guess size
119 data << uint32(entry); // creature entry
120 data << Name;
121 data << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4, always empty
122 data << Title;
123 data << ci->IconName; // "Directions" for guard, string for Icons 2.3.0
124 data << uint32(ci->type_flags); // flags
125 data << uint32(ci->type); // CreatureType.dbc
126 data << uint32(ci->family); // CreatureFamily.dbc
127 data << uint32(ci->rank); // Creature Rank (elite, boss, etc)
128 data << uint32(ci->KillCredit[0]); // new in 3.1, kill credit
129 data << uint32(ci->KillCredit[1]); // new in 3.1, kill credit
130 data << uint32(ci->Modelid1); // Modelid1
131 data << uint32(ci->Modelid2); // Modelid2
132 data << uint32(ci->Modelid3); // Modelid3
133 data << uint32(ci->Modelid4); // Modelid4
134 data << float(ci->ModHealth); // dmg/hp modifier
135 data << float(ci->ModMana); // dmg/mana modifier
136 data << uint8(ci->RacialLeader);
137
138 CreatureQuestItemList const* items = sObjectMgr->GetCreatureQuestItemList(entry);
139 if (items)
140 for (size_t i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i)
141 data << (i < items->size() ? uint32((*items)[i]) : uint32(0));
142 else
143 for (size_t i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i)
144 data << uint32(0);
145
146 data << uint32(ci->movementId); // CreatureMovementInfo.dbc
147 SendPacket(&data);
148 }
149 else
150 {
151 LOG_DEBUG("network", "WORLD: CMSG_CREATURE_QUERY - NO CREATURE INFO! ({})", guid.ToString());
153 data << uint32(entry | 0x80000000);
154 SendPacket(&data);
155 LOG_DEBUG("network", "WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE");
156 }
157}
LocaleConstant
Definition: Common.h:74
std::vector< uint32 > CreatureQuestItemList
Definition: CreatureData.h:277
#define MAX_CREATURE_QUEST_ITEMS
Definition: CreatureData.h:37
@ SMSG_CREATURE_QUERY_RESPONSE
Definition: Opcodes.h:127
std::string SubName
Definition: CreatureData.h:185
std::string Name
Definition: CreatureData.h:184
uint32 KillCredit[MAX_KILL_CREDIT]
Definition: CreatureData.h:179
std::string IconName
Definition: CreatureData.h:186
static std::string_view GetLocaleString(std::vector< std::string > const &data, size_t locale)
Definition: ObjectMgr.h:1390

◆ HandleDelFriendOpcode()

void WorldSession::HandleDelFriendOpcode ( WorldPacket recvPacket)

Definition at line 97 of file Socialhandler.cpp.

98{
99 ObjectGuid FriendGUID;
100 recv_data >> FriendGUID;
101
103
104 sSocialMgr->SendFriendStatus(GetPlayer(), FRIEND_REMOVED, FriendGUID, false);
105
106 LOG_DEBUG("network", "WORLD: Sent motd (SMSG_FRIEND_STATUS)");
107}
@ FRIEND_REMOVED
Definition: SocialMgr.h:72
void RemoveFromSocialList(ObjectGuid friend_guid, SocialFlag flag)
Definition: SocialMgr.cpp:74

◆ HandleDelIgnoreOpcode()

void WorldSession::HandleDelIgnoreOpcode ( WorldPacket recvPacket)

Definition at line 144 of file Socialhandler.cpp.

145{
146 ObjectGuid IgnoreGUID;
147 recv_data >> IgnoreGUID;
148
150 sSocialMgr->SendFriendStatus(GetPlayer(), FRIEND_IGNORE_REMOVED, IgnoreGUID, false);
151}
@ FRIEND_IGNORE_REMOVED
Definition: SocialMgr.h:83

◆ HandleDestroyItemOpcode()

void WorldSession::HandleDestroyItemOpcode ( WorldPacket recvPacket)

Definition at line 295 of file ItemHandler.cpp.

296{
297 //LOG_DEBUG("network.opcode", "WORLD: CMSG_DESTROYITEM");
298 uint8 bag, slot, count, data1, data2, data3;
299
300 recvData >> bag >> slot >> count >> data1 >> data2 >> data3;
301
302 uint16 pos = (bag << 8) | slot;
303
304 // prevent drop unequipable items (in combat, for example) and non-empty bags
305 if (_player->IsEquipmentPos(pos) || _player->IsBagPos(pos))
306 {
307 InventoryResult msg = _player->CanUnequipItem(pos, false);
308 if (msg != EQUIP_ERR_OK)
309 {
310 _player->SendEquipError(msg, _player->GetItemByPos(pos), nullptr);
311 return;
312 }
313 }
314
315 Item* pItem = _player->GetItemByPos(bag, slot);
316 if (!pItem)
317 {
319 return;
320 }
321
323 {
325 return;
326 }
327
328 recoveryItem(pItem);
329
330 if (count)
331 {
332 uint32 i_count = count;
333 _player->DestroyItemCount(pItem, i_count, true);
334 }
335 else
336 {
337 _player->DestroyItem(bag, slot, true);
338 }
340}
@ EQUIP_ERR_CANT_DROP_SOULBOUND
Definition: Item.h:65
@ ITEM_FLAG_NO_USER_DESTROY
Definition: ItemTemplate.h:153
void SendQuestGiverStatusMultiple()
Definition: Player.cpp:7552
bool recoveryItem(Item *pItem)

◆ HandleDismissControlledVehicle()

void WorldSession::HandleDismissControlledVehicle ( WorldPacket recvData)

Definition at line 26 of file VehicleHandler.cpp.

27{
28 LOG_DEBUG("network", "WORLD: Recvd CMSG_DISMISS_CONTROLLED_VEHICLE");
29
30 ObjectGuid vehicleGUID = _player->GetCharmGUID();
31
32 if (!vehicleGUID) // something wrong here...
33 {
34 recvData.rfinish(); // prevent warnings spam
35 return;
36 }
37
38 ObjectGuid guid;
39 recvData >> guid.ReadAsPacked();
40
41 // pussywizard: typical check for incomming movement packets
43 {
44 recvData.rfinish(); // prevent warnings spam
46 return;
47 }
48
49 MovementInfo mi;
50 mi.guid = guid;
51 ReadMovementInfo(recvData, &mi);
52
54
56}
bool IsDuringRemoveFromWorld() const
Definition: Unit.h:2391
void ExitVehicle(Position const *exitPosition=nullptr)
Definition: Unit.cpp:19749

◆ HandleDismissCritter()

void WorldSession::HandleDismissCritter ( WorldPackets::Pet::DismissCritter dismissCritter)

Definition at line 39 of file PetHandler.cpp.

40{
41 Unit* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, packet.CritterGUID);
42
43 if (!pet)
44 {
45 LOG_DEBUG("network", "Vanitypet ({}) does not exist - player {} ({} / account: {}) attempted to dismiss it (possibly lagged out)",
46 packet.CritterGUID.ToString(), GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString(), GetAccountId());
47 return;
48 }
49
50 if (_player->GetCritterGUID() == pet->GetGUID())
51 {
52 if (pet->GetTypeId() == TYPEID_UNIT && pet->ToCreature()->IsSummon())
53 pet->ToTempSummon()->UnSummon();
54 }
55}
Creature * GetCreatureOrPetOrVehicle(WorldObject const &, ObjectGuid const)
virtual void UnSummon(uint32 msTime=0)
TempSummon * ToTempSummon()
Definition: Unit.h:2395
bool IsSummon() const
Definition: Unit.h:1410
ObjectGuid GetCritterGUID() const
Definition: Unit.h:1823

◆ HandleDuelAcceptedOpcode()

void WorldSession::HandleDuelAcceptedOpcode ( WorldPacket recvPacket)

Definition at line 26 of file DuelHandler.cpp.

27{
28 Player* player = GetPlayer();
29 if (!player->duel || player == player->duel->Initiator || player->duel->State != DUEL_STATE_CHALLENGED)
30 return;
31
32 ObjectGuid guid;
33 recvPacket >> guid;
34
35 Player* target = player->duel->Opponent;
36 if (target->GetGuidValue(PLAYER_DUEL_ARBITER) != guid)
37 return;
38
39 LOG_DEBUG("network.opcode", "Player 1 is: {} ({})", player->GetGUID().ToString(), player->GetName());
40 LOG_DEBUG("network.opcode", "Player 2 is: {} ({})", target->GetGUID().ToString(), target->GetName());
41
42 time_t now = GameTime::GetGameTime().count();
43 player->duel->StartTime = now + 3;
44 target->duel->StartTime = now + 3;
45
46 player->duel->State = DUEL_STATE_COUNTDOWN;
47 target->duel->State = DUEL_STATE_COUNTDOWN;
48
49 player->SendDuelCountdown(3000);
50 target->SendDuelCountdown(3000);
51}
@ PLAYER_DUEL_ARBITER
Definition: UpdateFields.h:177
@ DUEL_STATE_CHALLENGED
Definition: Player.h:371
@ DUEL_STATE_COUNTDOWN
Definition: Player.h:372
ObjectGuid GetGuidValue(uint16 index) const
Definition: Object.cpp:337
void SendDuelCountdown(uint32 counter)
Definition: Player.cpp:15038
std::unique_ptr< DuelInfo > duel
Definition: Player.h:1827

◆ HandleDuelCancelledOpcode()

void WorldSession::HandleDuelCancelledOpcode ( WorldPacket recvPacket)

Definition at line 53 of file DuelHandler.cpp.

54{
55 LOG_DEBUG("network", "WORLD: Received CMSG_DUEL_CANCELLED");
56 Player* player = GetPlayer();
57
58 ObjectGuid guid;
59 recvPacket >> guid;
60
61 // no duel requested
62 if (!player->duel || player->duel->State == DUEL_STATE_COMPLETED)
63 return;
64
65 // player surrendered in a duel using /forfeit
66 if (GetPlayer()->duel->State == DUEL_STATE_IN_PROGRESS)
67 {
69 GetPlayer()->duel->Opponent->CombatStopWithPets(true);
70
71 GetPlayer()->CastSpell(GetPlayer(), 7267, true); // beg
73 return;
74 }
75
77}
@ DUEL_STATE_COMPLETED
Definition: Player.h:374
@ DUEL_STATE_IN_PROGRESS
Definition: Player.h:373
@ DUEL_WON
@ DUEL_INTERRUPTED
void DuelComplete(DuelCompleteType type)
Definition: Player.cpp:6293
SpellCastResult CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
Definition: Unit.cpp:1168
void CombatStopWithPets(bool includingCast=false)
Definition: Unit.cpp:10405

◆ HandleEjectPassenger()

void WorldSession::HandleEjectPassenger ( WorldPacket data)

Definition at line 162 of file VehicleHandler.cpp.

163{
164 Vehicle* vehicle = _player->GetVehicleKit();
165 if (!vehicle)
166 {
167 data.rfinish(); // prevent warnings spam
168 LOG_ERROR("network.opcode", "HandleEjectPassenger: Player {} is not in a vehicle!", GetPlayer()->GetGUID().ToString());
169 return;
170 }
171
172 ObjectGuid guid;
173 data >> guid;
174
175 if (guid.IsPlayer())
176 {
177 Player* player = ObjectAccessor::GetPlayer(*_player, guid);
178 if (!player)
179 {
180 LOG_ERROR("network.opcode", "Player {} tried to eject player {} from vehicle, but the latter was not found in world!", GetPlayer()->GetGUID().ToString(), guid.ToString());
181 return;
182 }
183
184 if (!player->IsOnVehicle(vehicle->GetBase()))
185 {
186 LOG_ERROR("network.opcode", "Player {} tried to eject player {}, but they are not in the same vehicle", GetPlayer()->GetGUID().ToString(), guid.ToString());
187 return;
188 }
189
190 VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(player);
191 ASSERT(seat);
192 if (seat->IsEjectable())
193 player->ExitVehicle();
194 else
195 LOG_ERROR("network.opcode", "Player {} attempted to eject player {} from non-ejectable seat.", GetPlayer()->GetGUID().ToString(), guid.ToString());
196 }
197 else if (guid.IsCreature())
198 {
199 Unit* unit = ObjectAccessor::GetUnit(*_player, guid);
200 if (!unit) // creatures can be ejected too from player mounts
201 {
202 LOG_ERROR("network.opcode", "Player {} tried to eject creature guid {} from vehicle, but the latter was not found in world!", GetPlayer()->GetGUID().ToString(), guid.ToString());
203 return;
204 }
205
206 if (!unit->IsOnVehicle(vehicle->GetBase()))
207 {
208 LOG_ERROR("network.opcode", "Player {} tried to eject unit {}, but they are not in the same vehicle", GetPlayer()->GetGUID().ToString(), guid.ToString());
209 return;
210 }
211
212 VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(unit);
213 ASSERT(seat);
214 if (seat->IsEjectable())
215 {
216 ASSERT(GetPlayer() == vehicle->GetBase());
217 unit->ExitVehicle();
218 }
219 else
220 LOG_ERROR("network.opcode", "Player {} attempted to eject creature {} from non-ejectable seat.", GetPlayer()->GetGUID().ToString(), guid.ToString());
221 }
222 else
223 LOG_ERROR("network.opcode", "HandleEjectPassenger: Player {} tried to eject invalid {}", GetPlayer()->GetGUID().ToString(), guid.ToString());
224}
bool IsPlayer() const
Definition: ObjectGuid.h:170
bool IsCreature() const
Definition: ObjectGuid.h:164
bool IsOnVehicle(Unit const *vehicle) const
Definition: Unit.h:2350
Unit * GetBase() const
May be called from scripts.
Definition: Vehicle.h:39
bool IsEjectable() const

◆ HandleEmoteOpcode()

void WorldSession::HandleEmoteOpcode ( WorldPackets::Chat::EmoteClient packet)

Definition at line 669 of file ChatHandler.cpp.

670{
671 if (GetPlayer()->IsSpectator())
672 return;
673
674 uint32 emoteId = packet.EmoteID;
675
676 // restrict to the only emotes hardcoded in client
677 if (emoteId != EMOTE_ONESHOT_NONE && emoteId != EMOTE_ONESHOT_WAVE)
678 return;
679
681 return;
682
683 sScriptMgr->OnPlayerEmote(_player, emoteId);
684 _player->HandleEmoteCommand(emoteId);
685}
@ EMOTE_ONESHOT_NONE
@ EMOTE_ONESHOT_WAVE
void HandleEmoteCommand(uint32 emoteId)
Definition: Unit.cpp:1958

◆ HandleEnterPlayerVehicle()

void WorldSession::HandleEnterPlayerVehicle ( WorldPacket data)

Definition at line 140 of file VehicleHandler.cpp.

141{
142 // Read guid
143 ObjectGuid guid;
144 data >> guid;
145
146 if (Player* player = ObjectAccessor::GetPlayer(*_player, guid))
147 {
148 if (!player->GetVehicleKit())
149 return;
150 if (!player->IsInRaidWith(_player))
151 return;
152 if (!player->IsWithinDistInMap(_player, INTERACTION_DISTANCE))
153 return;
154 // Xinef:
156 return;
157
158 _player->EnterVehicle(player);
159 }
160}
void EnterVehicle(Unit *base, int8 seatId=-1)
Definition: Unit.cpp:19651
bool IsBattleArena() const
Definition: Map.h:454

◆ HandleEquipmentSetDelete()

void WorldSession::HandleEquipmentSetDelete ( WorldPacket recvData)

Definition at line 1812 of file CharacterHandler.cpp.

1813{
1814 LOG_DEBUG("network", "CMSG_EQUIPMENT_SET_DELETE");
1815
1816 uint64 setGuid;
1817 recvData.readPackGUID(setGuid);
1818
1819 _player->DeleteEquipmentSet(setGuid);
1820}
void DeleteEquipmentSet(uint64 setGuid)
Definition: Player.cpp:14313
void readPackGUID(uint64 &guid)
Definition: ByteBuffer.h:387

◆ HandleEquipmentSetSave()

void WorldSession::HandleEquipmentSetSave ( WorldPacket recvData)

Definition at line 1753 of file CharacterHandler.cpp.

1754{
1755 LOG_DEBUG("network", "CMSG_EQUIPMENT_SET_SAVE");
1756
1757 uint64 setGuid;
1758 recvData.readPackGUID(setGuid);
1759
1760 uint32 index;
1761 recvData >> index;
1762 if (index >= MAX_EQUIPMENT_SET_INDEX) // client set slots amount
1763 return;
1764
1765 std::string name;
1766 recvData >> name;
1767
1768 std::string iconName;
1769 recvData >> iconName;
1770
1771 EquipmentSet eqSet;
1772
1773 eqSet.Guid = setGuid;
1774 eqSet.Name = name;
1775 eqSet.IconName = iconName;
1776 eqSet.state = EQUIPMENT_SET_NEW;
1777
1778 for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i)
1779 {
1780 ObjectGuid itemGuid;
1781 recvData >> itemGuid.ReadAsPacked();
1782
1783 // xinef: if client sends 0, it means empty slot
1784 if (!itemGuid)
1785 {
1786 eqSet.Items[i].Clear();
1787 continue;
1788 }
1789
1790 // equipment manager sends "1" (as raw GUID) for slots set to "ignore" (don't touch slot at equip set)
1791 if (itemGuid.GetRawValue() == 1)
1792 {
1793 // ignored slots saved as bit mask because we have no free special values for Items[i]
1794 eqSet.IgnoreMask |= 1 << i;
1795 continue;
1796 }
1797
1798 // xinef: some cheating checks
1800 if (!item || item->GetGUID() != itemGuid)
1801 {
1802 eqSet.Items[i].Clear();
1803 continue;
1804 }
1805
1806 eqSet.Items[i] = itemGuid;
1807 }
1808
1809 _player->SetEquipmentSet(index, eqSet);
1810}
@ EQUIPMENT_SET_NEW
Definition: Player.h:745
#define MAX_EQUIPMENT_SET_INDEX
Definition: Player.h:761
@ EQUIPMENT_SLOT_END
Definition: Player.h:695
uint64 GetRawValue() const
Definition: ObjectGuid.h:144
ObjectGuid Items[EQUIPMENT_SLOT_END]
Definition: Player.h:757
std::string Name
Definition: Player.h:754
std::string IconName
Definition: Player.h:755
EquipmentSetUpdateState state
Definition: Player.h:758
uint64 Guid
Definition: Player.h:753
uint32 IgnoreMask
Definition: Player.h:756
void SetEquipmentSet(uint32 index, EquipmentSet eqset)
Definition: Player.cpp:14197

◆ HandleEquipmentSetUse()

void WorldSession::HandleEquipmentSetUse ( WorldPacket recvData)

Definition at line 1822 of file CharacterHandler.cpp.

1823{
1824 LOG_DEBUG("network", "CMSG_EQUIPMENT_SET_USE");
1825
1826 for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i)
1827 {
1828 ObjectGuid itemGuid;
1829 recvData >> itemGuid.ReadAsPacked();
1830
1831 uint8 srcbag, srcslot;
1832 recvData >> srcbag >> srcslot;
1833
1834 LOG_DEBUG("entities.player.items", "Item {}: srcbag {}, srcslot {}", itemGuid.ToString(), srcbag, srcslot);
1835
1836 // check if item slot is set to "ignored" (raw value == 1), must not be unequipped then
1837 if (itemGuid.GetRawValue() == 1)
1838 continue;
1839
1840 // Only equip weapons in combat
1842 continue;
1843
1844 Item* item = nullptr;
1845 if (itemGuid)
1846 item = _player->GetItemByGuid(itemGuid);
1847
1848 uint16 dstpos = i | (INVENTORY_SLOT_BAG_0 << 8);
1849
1850 InventoryResult msg;
1851
1853 if (uItem)
1854 {
1855 if (uItem->IsEquipped())
1856 {
1857 msg = _player->CanUnequipItem(dstpos, true);
1858 if (msg != EQUIP_ERR_OK)
1859 {
1860 _player->SendEquipError(msg, uItem, nullptr);
1861 continue;
1862 }
1863 }
1864
1865 if (!item)
1866 {
1867 ItemPosCountVec sDest;
1868 msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, sDest, uItem, false);
1869 if (msg == EQUIP_ERR_OK)
1870 {
1872 _player->StoreItem(sDest, uItem, true);
1873 }
1874 else
1875 _player->SendEquipError(msg, uItem, nullptr);
1876
1877 continue;
1878 }
1879 }
1880
1881 if (item)
1882 {
1883 if (item->GetPos() == dstpos)
1884 continue;
1885
1886 if (!item->IsEquipped())
1887 {
1888 uint16 _candidatePos;
1889 msg = _player->CanEquipItem(NULL_SLOT, _candidatePos, item, true);
1890 if (msg != EQUIP_ERR_OK)
1891 {
1892 _player->SendEquipError(msg, item, nullptr);
1893 continue;
1894 }
1895 }
1896
1897 _player->SwapItem(item->GetPos(), dstpos);
1898 }
1899 }
1900
1902 data << uint8(0); // 4 - equipment swap failed - inventory is full
1903 SendPacket(&data);
1904}
@ EQUIPMENT_SLOT_MAINHAND
Definition: Player.h:691
@ EQUIPMENT_SLOT_OFFHAND
Definition: Player.h:692
@ EQUIPMENT_SLOT_RANGED
Definition: Player.h:693
@ SMSG_EQUIPMENT_SET_USE_RESULT
Definition: Opcodes.h:1268
bool IsEquipped() const
Definition: Item.cpp:791

◆ HandleFarSightOpcode()

void WorldSession::HandleFarSightOpcode ( WorldPacket recvData)

Definition at line 1239 of file MiscHandler.cpp.

1240{
1241 LOG_DEBUG("network", "WORLD: CMSG_FAR_SIGHT");
1242
1243 bool apply;
1244 recvData >> apply;
1245
1246 if (apply)
1247 {
1248 LOG_DEBUG("network", "Added FarSight {} to player {}", _player->GetGuidValue(PLAYER_FARSIGHT).ToString(), _player->GetGUID().ToString());
1249 if (WorldObject* target = _player->GetViewpoint())
1250 _player->SetSeer(target);
1251 else
1252 LOG_DEBUG("network.opcode", "Player {} requests non-existing seer {}", _player->GetName(), _player->GetGuidValue(PLAYER_FARSIGHT).ToString());
1253 }
1254 else
1255 {
1256 WorldObject* newFarsightobject = nullptr;
1257 if (WorldObject* viewpoint = _player->GetViewpoint())
1258 {
1259 if (DynamicObject* viewpointDynamicObject = viewpoint->ToDynObject())
1260 {
1261 newFarsightobject = ObjectAccessor::GetUnit(*viewpointDynamicObject, viewpointDynamicObject->GetOldFarsightGUID());
1262 }
1263 else if (DynamicObject* viewpointDynamicObject = _player->GetDynObject(_player->GetUInt32Value(UNIT_CHANNEL_SPELL)))
1264 {
1265 if (viewpointDynamicObject->IsViewpoint() && viewpointDynamicObject->GetCasterGUID() == _player->GetGUID())
1266 {
1267 newFarsightobject = viewpointDynamicObject;
1268 }
1269 }
1270 }
1271
1272 if (newFarsightobject)
1273 {
1274 LOG_DEBUG("network", "Player {} set vision to old farsight {}", _player->GetGUID().ToString(), newFarsightobject->GetGUID().ToString());
1276 _player->SetViewpoint(newFarsightobject, true);
1277 }
1278 else
1279 {
1280 LOG_DEBUG("network", "Player {} set vision to self", _player->GetGUID().ToString());
1282 }
1283 }
1284
1286}
@ PLAYER_FARSIGHT
Definition: UpdateFields.h:334
@ UNIT_CHANNEL_SPELL
Definition: UpdateFields.h:94
void apply(T *val)
Definition: ByteConverter.h:40
DynamicObject * ToDynObject()
Definition: Object.h:208
void SetSeer(WorldObject *target)
Definition: Player.h:2297
void UpdateVisibilityForPlayer(bool mapChange=false)
void SetViewpoint(WorldObject *target, bool apply)
Definition: Player.cpp:12878
WorldObject * GetViewpoint() const
Definition: Player.cpp:12921
DynamicObject * GetDynObject(uint32 spellId)
Definition: Unit.cpp:6028

◆ HandleFeatherFallAck()

void WorldSession::HandleFeatherFallAck ( WorldPacket recvData)

Definition at line 998 of file MiscHandler.cpp.

999{
1000 LOG_DEBUG("network", "WORLD: CMSG_MOVE_FEATHER_FALL_ACK");
1001
1002 // no used
1003 recv_data.rfinish(); // prevent warnings spam
1004}

◆ HandleForceSpeedChangeAck()

void WorldSession::HandleForceSpeedChangeAck ( WorldPacket recvData)

Definition at line 608 of file MovementHandler.cpp.

609{
610 uint32 opcode = recvData.GetOpcode();
611 LOG_DEBUG("network", "WORLD: Recvd {} ({}, 0x{:X}) opcode", GetOpcodeNameForLogging(static_cast<OpcodeClient>(opcode)), opcode, opcode);
612
613 /* extract packet */
614 ObjectGuid guid;
615 uint32 unk1;
616 float newspeed;
617
618 recvData >> guid.ReadAsPacked();
619
620 // pussywizard: special check, only player mover allowed here
621 if (guid != _player->m_mover->GetGUID() || guid != _player->GetGUID())
622 {
623 recvData.rfinish(); // prevent warnings spam
624 return;
625 }
626
627 // continue parse packet
628 recvData >> unk1; // counter or moveEvent
629
630 MovementInfo movementInfo;
631 movementInfo.guid = guid;
632 ReadMovementInfo(recvData, &movementInfo);
633
634 recvData >> newspeed;
635
636 // client ACK send one packet for mounted/run case and need skip all except last from its
637 // in other cases anti-cheat check can be fail in false case
638 UnitMoveType move_type;
639 UnitMoveType force_move_type;
640
641 static char const* move_type_name[MAX_MOVE_TYPE] = { "Walk", "Run", "RunBack", "Swim", "SwimBack", "TurnRate", "Flight", "FlightBack", "PitchRate" };
642
643 switch (opcode)
644 {
646 move_type = MOVE_WALK;
647 force_move_type = MOVE_WALK;
648 break;
650 move_type = MOVE_RUN;
651 force_move_type = MOVE_RUN;
652 break;
654 move_type = MOVE_RUN_BACK;
655 force_move_type = MOVE_RUN_BACK;
656 break;
658 move_type = MOVE_SWIM;
659 force_move_type = MOVE_SWIM;
660 break;
662 move_type = MOVE_SWIM_BACK;
663 force_move_type = MOVE_SWIM_BACK;
664 break;
666 move_type = MOVE_TURN_RATE;
667 force_move_type = MOVE_TURN_RATE;
668 break;
670 move_type = MOVE_FLIGHT;
671 force_move_type = MOVE_FLIGHT;
672 break;
674 move_type = MOVE_FLIGHT_BACK;
675 force_move_type = MOVE_FLIGHT_BACK;
676 break;
678 move_type = MOVE_PITCH_RATE;
679 force_move_type = MOVE_PITCH_RATE;
680 break;
681 default:
682 LOG_ERROR("network.opcode", "WorldSession::HandleForceSpeedChangeAck: Unknown move type opcode: {}", opcode);
683 return;
684 }
685
686 sScriptMgr->AnticheatSetUnderACKmount(_player);
687
688 // skip all forced speed changes except last and unexpected
689 // in run/mounted case used one ACK and it must be skipped.m_forced_speed_changes[MOVE_RUN} store both.
690 if (_player->m_forced_speed_changes[force_move_type] > 0)
691 {
692 --_player->m_forced_speed_changes[force_move_type];
693 if (_player->m_forced_speed_changes[force_move_type] > 0)
694 return;
695 }
696
697 if (!_player->GetTransport() && std::fabs(_player->GetSpeed(move_type) - newspeed) > 0.01f)
698 {
699 if (_player->GetSpeed(move_type) > newspeed) // must be greater - just correct
700 {
701 LOG_ERROR("network.opcode", "{}SpeedChange player {} is NOT correct (must be {} instead {}), force set to correct value",
702 move_type_name[move_type], _player->GetName(), _player->GetSpeed(move_type), newspeed);
703 _player->SetSpeed(move_type, _player->GetSpeedRate(move_type), true);
704 }
705 else // must be lesser - cheating
706 {
707 LOG_INFO("network.opcode", "Player {} from account id {} kicked for incorrect speed (must be {} instead {})",
708 _player->GetName(), GetAccountId(), _player->GetSpeed(move_type), newspeed);
709 KickPlayer("Incorrect speed");
710 }
711 }
712}
#define MAX_MOVE_TYPE
Definition: Unit.h:389
UnitMoveType
Definition: Unit.h:377
@ MOVE_FLIGHT
Definition: Unit.h:384
@ MOVE_SWIM
Definition: Unit.h:381
@ MOVE_TURN_RATE
Definition: Unit.h:383
@ MOVE_FLIGHT_BACK
Definition: Unit.h:385
@ MOVE_SWIM_BACK
Definition: Unit.h:382
@ MOVE_RUN
Definition: Unit.h:379
@ MOVE_PITCH_RATE
Definition: Unit.h:386
@ MOVE_RUN_BACK
Definition: Unit.h:380
@ MOVE_WALK
Definition: Unit.h:378
@ CMSG_FORCE_PITCH_RATE_CHANGE_ACK
Definition: Opcodes.h:1147
@ CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK
Definition: Opcodes.h:259
@ CMSG_FORCE_TURN_RATE_CHANGE_ACK
Definition: Opcodes.h:765
@ CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK
Definition: Opcodes.h:930
@ CMSG_FORCE_SWIM_SPEED_CHANGE_ACK
Definition: Opcodes.h:261
@ CMSG_FORCE_RUN_SPEED_CHANGE_ACK
Definition: Opcodes.h:257
@ CMSG_FORCE_WALK_SPEED_CHANGE_ACK
Definition: Opcodes.h:761
@ CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK
Definition: Opcodes.h:928
@ CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK
Definition: Opcodes.h:763
Transport * GetTransport() const
Definition: Object.h:585
uint8 m_forced_speed_changes[MAX_MOVE_TYPE]
Definition: Player.h:2349
float GetSpeed(UnitMoveType mtype) const
Definition: Unit.cpp:14296
float GetSpeedRate(UnitMoveType mtype) const
Definition: Unit.h:2243
void SetSpeed(UnitMoveType mtype, float rate, bool forced=false)
Definition: Unit.cpp:14301

◆ HandleGameObjectQueryOpcode()

void WorldSession::HandleGameObjectQueryOpcode ( WorldPacket recvPacket)

Only static data is sent in this packet !!!

Definition at line 160 of file QueryHandler.cpp.

161{
162 uint32 entry;
163 recvData >> entry;
164 ObjectGuid guid;
165 recvData >> guid;
166
167 const GameObjectTemplate* info = sObjectMgr->GetGameObjectTemplate(entry);
168 if (info)
169 {
170 std::string Name;
171 std::string IconName;
172 std::string CastBarCaption;
173
174 Name = info->name;
175 IconName = info->IconName;
176 CastBarCaption = info->castBarCaption;
177
178 LocaleConstant localeConstant = GetSessionDbLocaleIndex();
179 if (localeConstant >= LOCALE_enUS)
180 if (GameObjectLocale const* gameObjectLocale = sObjectMgr->GetGameObjectLocale(entry))
181 {
182 ObjectMgr::GetLocaleString(gameObjectLocale->Name, localeConstant, Name);
183 ObjectMgr::GetLocaleString(gameObjectLocale->CastBarCaption, localeConstant, CastBarCaption);
184 }
185
186 LOG_DEBUG("network", "WORLD: CMSG_GAMEOBJECT_QUERY '{}' - Entry: {}. ", info->name, entry);
188 data << uint32(entry);
189 data << uint32(info->type);
190 data << uint32(info->displayId);
191 data << Name;
192 data << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4
193 data << IconName; // 2.0.3, string. Icon name to use instead of default icon for go's (ex: "Attack" makes sword)
194 data << CastBarCaption; // 2.0.3, string. Text will appear in Cast Bar when using GO (ex: "Collecting")
195 data << info->unk1; // 2.0.3, string
196 data.append(info->raw.data, MAX_GAMEOBJECT_DATA);
197 data << float(info->size); // go size
198
199 GameObjectQuestItemList const* items = sObjectMgr->GetGameObjectQuestItemList(entry);
200 if (items)
201 for (size_t i = 0; i < MAX_GAMEOBJECT_QUEST_ITEMS; ++i)
202 data << (i < items->size() ? uint32((*items)[i]) : uint32(0));
203 else
204 for (size_t i = 0; i < MAX_GAMEOBJECT_QUEST_ITEMS; ++i)
205 data << uint32(0);
206
207 SendPacket(&data);
208 LOG_DEBUG("network", "WORLD: Sent SMSG_GAMEOBJECT_QUERY_RESPONSE");
209 }
210 else
211 {
212 LOG_DEBUG("network", "WORLD: CMSG_GAMEOBJECT_QUERY - Missing gameobject info for ({})", guid.ToString());
214 data << uint32(entry | 0x80000000);
215 SendPacket(&data);
216 LOG_DEBUG("network", "WORLD: Sent SMSG_GAMEOBJECT_QUERY_RESPONSE");
217 }
218}
@ LOCALE_enUS
Definition: Common.h:75
#define MAX_GAMEOBJECT_QUEST_ITEMS
Definition: GameObject.h:37
std::vector< uint32 > GameObjectQuestItemList
Definition: GameObject.h:791
#define MAX_GAMEOBJECT_DATA
@ SMSG_GAMEOBJECT_QUERY_RESPONSE
Definition: Opcodes.h:125
uint32 data[MAX_GAMEOBJECT_DATA]
Definition: GameObject.h:398
std::string unk1
Definition: GameObject.h:48
std::string name
Definition: GameObject.h:45
struct GameObjectTemplate::@209::@239 raw
std::string castBarCaption
Definition: GameObject.h:47
std::string IconName
Definition: GameObject.h:46

◆ HandleGameobjectReportUse()

void WorldSession::HandleGameobjectReportUse ( WorldPacket recvPacket)

Definition at line 313 of file SpellHandler.cpp.

314{
315 ObjectGuid guid;
316 recvPacket >> guid;
317
318 LOG_DEBUG("network", "WORLD: Recvd CMSG_GAMEOBJ_REPORT_USE Message [{}]", guid.ToString());
319
320 // ignore for remote control state
321 if (_player->m_mover != _player)
322 return;
323
324 GameObject* go = GetPlayer()->GetMap()->GetGameObject(guid);
325 if (!go)
326 return;
327
329 return;
330
331 if (go->AI()->GossipHello(_player, true))
332 return;
333
335}
@ ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT
Definition: DBCEnums.h:186
virtual bool GossipHello(Player *, bool)
Definition: GameObjectAI.h:54
GameObjectAI * AI() const
Definition: GameObject.h:1001

◆ HandleGameObjectUseOpcode()

void WorldSession::HandleGameObjectUseOpcode ( WorldPacket recPacket)

Definition at line 292 of file SpellHandler.cpp.

293{
294 ObjectGuid guid;
295 recvData >> guid;
296
297 LOG_DEBUG("network", "WORLD: Recvd CMSG_GAMEOBJ_USE Message [{}]", guid.ToString());
298
299 if (GameObject* obj = GetPlayer()->GetMap()->GetGameObject(guid))
300 {
301 if (!obj->IsWithinDistInMap(GetPlayer(), obj->GetInteractionDistance()))
302 return;
303
304 // ignore for remote control state
305 if (GetPlayer()->m_mover != GetPlayer())
306 if (!(GetPlayer()->IsOnVehicle(GetPlayer()->m_mover) || GetPlayer()->IsMounted()) && !obj->GetGOInfo()->IsUsableMounted())
307 return;
308
309 obj->Use(GetPlayer());
310 }
311}
GameObject * GetGameObject(WorldObject const &u, ObjectGuid const guid)

◆ HandleGetChannelMemberCount()

void WorldSession::HandleGetChannelMemberCount ( WorldPacket recvPacket)

Definition at line 285 of file ChannelHandler.cpp.

286{
287 std::string channelName;
288 recvPacket >> channelName;
289
290 LOG_DEBUG("chat.system", "CMSG_GET_CHANNEL_MEMBER_COUNT {} Channel: {}",
291 GetPlayerInfo(), channelName);
293 {
294 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
295 {
296 LOG_DEBUG("chat.system", "SMSG_CHANNEL_MEMBER_COUNT {} Channel: {} Count: {}",
297 GetPlayerInfo(), channelName, channel->GetNumPlayers());
298
299 WorldPacket data(SMSG_CHANNEL_MEMBER_COUNT, channel->GetName().size() + 1 + 4);
300 data << channel->GetName();
301 data << uint8(channel->GetFlags());
302 data << uint32(channel->GetNumPlayers());
303 SendPacket(&data);
304 }
305 }
306}
@ SMSG_CHANNEL_MEMBER_COUNT
Definition: Opcodes.h:1011

◆ HandleGetMailList()

void WorldSession::HandleGetMailList ( WorldPacket recvData)

Definition at line 601 of file MailHandler.cpp.

602{
603 ObjectGuid mailbox;
604 recvData >> mailbox;
605
606 if (!CanOpenMailBox(mailbox))
607 return;
608
609 Player* player = _player;
610
611 uint8 mailsCount = 0;
612 uint32 realCount = 0;
613
614 WorldPacket data(SMSG_MAIL_LIST_RESULT, (200)); // guess size
615 data << uint32(0); // real mail's count
616 data << uint8(0); // mail's count
617 time_t cur_time = GameTime::GetGameTime().count();
618
619 for (Mail const* mail : player->GetMails())
620 {
621 // prevent client storage overflow
622 if (mailsCount >= MAX_INBOX_CLIENT_CAPACITY)
623 {
624 ++realCount;
625 continue;
626 }
627
628 // skip deleted or not delivered (deliver delay not expired) mails
629 if (mail->state == MAIL_STATE_DELETED || cur_time < mail->deliver_time || cur_time > mail->expire_time)
630 {
631 continue;
632 }
633
634 uint8 item_count = uint8(mail->items.size()); // max count is MAX_MAIL_ITEMS (12)
635
636 size_t next_mail_size = 2 + 4 + 1 + (mail->messageType == MAIL_NORMAL ? 8 : 4) + 4 * 8 + (mail->subject.size() + 1) + (mail->body.size() + 1) + 1 + item_count * (1 + 4 + 4 + MAX_INSPECTED_ENCHANTMENT_SLOT * 3 * 4 + 4 + 4 + 4 + 4 + 4 + 4 + 1);
637
638 if (data.wpos() + next_mail_size > MAX_NETCLIENT_PACKET_SIZE)
639 {
640 ++realCount;
641 continue;
642 }
643
644 data << uint16(next_mail_size); // Message size
645 data << uint32(mail->messageID); // Message ID
646 data << uint8(mail->messageType); // Message Type
647
648 switch (mail->messageType)
649 {
650 case MAIL_NORMAL: // sender guid
651 data << ObjectGuid::Create<HighGuid::Player>(mail->sender);
652 break;
653 case MAIL_CREATURE:
654 case MAIL_GAMEOBJECT:
655 case MAIL_AUCTION:
656 case MAIL_CALENDAR:
657 data << uint32(mail->sender); // creature/gameobject entry, auction id, calendar event id?
658 break;
659 }
660
661 // prevent client crash
662 std::string subject = mail->subject;
663 std::string body = mail->body;
664
665 if (subject.find("| |") != std::string::npos)
666 {
667 subject = "";
668 }
669 if (body.find("| |") != std::string::npos)
670 {
671 body = "";
672 }
673
674 data << uint32(mail->COD); // COD
675 data << uint32(0); // probably changed in 3.3.3
676 data << uint32(mail->stationery); // stationery (Stationery.dbc)
677 data << uint32(mail->money); // Gold
678 data << uint32(mail->checked); // flags
679 data << float(float(mail->expire_time - GameTime::GetGameTime().count()) / DAY); // Time
680 data << uint32(mail->mailTemplateId); // mail template (MailTemplate.dbc)
681 data << subject; // Subject string - once 00, when mail type = 3, max 256
682 data << body; // message? max 8000
683 data << uint8(item_count); // client limit is 0x10
684
685 for (uint8 i = 0; i < item_count; ++i)
686 {
687 Item* item = player->GetMItem(mail->items[i].item_guid);
688 // item index (0-6?)
689 data << uint8(i);
690 // item guid low?
691 data << uint32((item ? item->GetGUID().GetCounter() : 0));
692 // entry
693 data << uint32((item ? item->GetEntry() : 0));
694 for (uint8 j = 0; j < MAX_INSPECTED_ENCHANTMENT_SLOT; ++j)
695 {
696 data << uint32(item ? item->GetEnchantmentId(EnchantmentSlot(j)) : 0);
697 data << uint32(item ? item->GetEnchantmentDuration(EnchantmentSlot(j)) : 0);
698 data << uint32(item ? item->GetEnchantmentCharges(EnchantmentSlot(j)) : 0);
699 }
700 // can be negative
701 data << int32((item ? item->GetItemRandomPropertyId() : 0));
702 // unk
703 data << uint32((item ? item->GetItemSuffixFactor() : 0));
704 // stack count
705 data << uint32((item ? item->GetCount() : 0));
706 // charges
707 data << uint32((item ? item->GetSpellCharges() : 0));
708 // durability
709 data << uint32((item ? item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY) : 0));
710 // durability
711 data << uint32((item ? item->GetUInt32Value(ITEM_FIELD_DURABILITY) : 0));
712 // unknown wotlk
713 data << uint8(0);
714 }
715
716 ++realCount;
717 ++mailsCount;
718 }
719
720 data.put<uint32>(0, realCount); // this will display warning about undelivered mail to player if realCount > mailsCount
721 data.put<uint8>(4, mailsCount); // set real send mails to client
722 SendPacket(&data);
723
724 // recalculate m_nextMailDelivereTime and unReadMails
726}
constexpr auto DAY
Definition: Common.h:58
#define MAX_NETCLIENT_PACKET_SIZE
Definition: Common.h:53
EnchantmentSlot
Definition: Item.h:162
@ MAX_INSPECTED_ENCHANTMENT_SLOT
Definition: Item.h:170
@ ITEM_FIELD_DURABILITY
Definition: UpdateFields.h:69
@ ITEM_FIELD_MAXDURABILITY
Definition: UpdateFields.h:70
#define MAX_INBOX_CLIENT_CAPACITY
Definition: MailHandler.cpp:34
@ MAIL_STATE_DELETED
Definition: Mail.h:71
@ MAIL_AUCTION
Definition: Mail.h:39
@ MAIL_GAMEOBJECT
Definition: Mail.h:41
@ MAIL_CREATURE
Definition: Mail.h:40
@ MAIL_CALENDAR
Definition: Mail.h:42
@ MAIL_NORMAL
Definition: Mail.h:38
@ SMSG_MAIL_LIST_RESULT
Definition: Opcodes.h:601
int32 GetSpellCharges(uint8 index=0) const
Definition: Item.h:308
uint32 GetEnchantmentDuration(EnchantmentSlot slot) const
Definition: Item.h:296
int32 GetItemRandomPropertyId() const
Definition: Item.h:286
uint32 GetItemSuffixFactor() const
Definition: Item.h:287
uint32 GetEnchantmentCharges(EnchantmentSlot slot) const
Definition: Item.h:297
void UpdateNextMailTimeAndUnreads()
PlayerMails const & GetMails() const
Definition: Player.h:1611
Item * GetMItem(ObjectGuid::LowType itemLowGuid)
Definition: Player.h:1626
Definition: Mail.h:168
bool CanOpenMailBox(ObjectGuid guid)
Definition: MailHandler.cpp:36

◆ HandleGMResponseResolve()

void WorldSession::HandleGMResponseResolve ( WorldPacket recvPacket)

Definition at line 280 of file TicketHandler.cpp.

281{
282 // empty packet
283 if (GmTicket* ticket = sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID()))
284 {
285 uint8 getSurvey = 0;
286 if (float(rand_chance()) < sWorld->getFloatConfig(CONFIG_CHANCE_OF_GM_SURVEY))
287 getSurvey = 1;
288
290 data << uint8(getSurvey);
291 SendPacket(&data);
292
295 SendPacket(&data2);
296
297 sTicketMgr->CloseTicket(ticket->GetId(), GetPlayer()->GetGUID());
298 sTicketMgr->SendTicket(this, nullptr);
299 }
300}
double rand_chance()
Definition: Random.cpp:83
#define sTicketMgr
Definition: TicketMgr.h:258
@ GMTICKET_RESPONSE_TICKET_DELETED
Definition: TicketMgr.h:47
@ CONFIG_CHANCE_OF_GM_SURVEY
Definition: IWorld.h:193
@ SMSG_GMRESPONSE_STATUS_UPDATE
Definition: Opcodes.h:1295
@ SMSG_GMTICKET_DELETETICKET
Definition: Opcodes.h:566

◆ HandleGMSurveySubmit()

void WorldSession::HandleGMSurveySubmit ( WorldPacket recvPacket)

Definition at line 197 of file TicketHandler.cpp.

198{
199 uint32 nextSurveyID = sTicketMgr->GetNextSurveyID();
200 // just put the survey into the database
201 uint32 mainSurvey; // GMSurveyCurrentSurvey.dbc, column 1 (all 9) ref to GMSurveySurveys.dbc
202 recv_data >> mainSurvey;
203
204 std::unordered_set<uint32> surveyIds;
205 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
206
207 // sub_survey1, r1, comment1, sub_survey2, r2, comment2, sub_survey3, r3, comment3, sub_survey4, r4, comment4, sub_survey5, r5, comment5, sub_survey6, r6, comment6, sub_survey7, r7, comment7, sub_survey8, r8, comment8, sub_survey9, r9, comment9, sub_survey10, r10, comment10,
208 for (uint8 i = 0; i < 10; i++)
209 {
210 uint32 subSurveyId; // ref to i'th GMSurveySurveys.dbc field (all fields in that dbc point to fields in GMSurveyQuestions.dbc)
211 recv_data >> subSurveyId;
212 if (!subSurveyId)
213 break;
214
215 uint8 rank; // probably some sort of ref to GMSurveyAnswers.dbc
216 recv_data >> rank;
217 std::string comment; // comment ("Usage: GMSurveyAnswerSubmit(question, rank, comment)")
218 recv_data >> comment;
219
220 if (!ValidateHyperlinksAndMaybeKick(comment))
221 {
222 return;
223 }
224
225 // make sure the same sub survey is not added to DB twice
226 if (!surveyIds.insert(subSurveyId).second)
227 continue;
228
230 stmt->SetData(0, nextSurveyID);
231 stmt->SetData(1, subSurveyId);
232 stmt->SetData(2, rank);
233 stmt->SetData(3, comment);
234 trans->Append(stmt);
235 }
236
237 std::string comment; // just a guess
238 recv_data >> comment;
239
240 if (!ValidateHyperlinksAndMaybeKick(comment))
241 {
242 return;
243 }
244
246 stmt->SetData(0, GetPlayer()->GetGUID().GetCounter());
247 stmt->SetData(1, nextSurveyID);
248 stmt->SetData(2, mainSurvey);
249 stmt->SetData(3, comment);
250
251 trans->Append(stmt);
252
253 CharacterDatabase.CommitTransaction(trans);
254}
@ CHAR_INS_GM_SURVEY
@ CHAR_INS_GM_SUBSURVEY
bool ValidateHyperlinksAndMaybeKick(std::string_view str)

◆ HandleGMTicketCreateOpcode()

void WorldSession::HandleGMTicketCreateOpcode ( WorldPacket recvPacket)

Definition at line 30 of file TicketHandler.cpp.

31{
32 // Don't accept tickets if the ticket queue is disabled. (Ticket UI is greyed out but not fully dependable)
34 return;
35
36 if (GetPlayer()->getLevel() < sWorld->getIntConfig(CONFIG_TICKET_LEVEL_REQ))
37 {
39 return;
40 }
41
43 GmTicket* ticket = sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID());
44
45 if (ticket && ticket->IsCompleted())
46 sTicketMgr->CloseTicket(ticket->GetId(), GetPlayer()->GetGUID());
47
48 // Player must not have ticket
49 if (!ticket || ticket->IsClosed())
50 {
51 uint32 mapId;
52 float x, y, z;
53 std::string message;
54 uint32 needResponse;
55 bool needMoreHelp;
56 uint32 count;
57 std::list<uint32> times;
58 uint32 decompressedSize;
59 std::string chatLog;
60
61 recvData >> mapId;
62 recvData >> x >> y >> z;
63 recvData >> message;
64
66 {
67 return;
68 }
69
70 recvData >> needResponse;
71 recvData >> needMoreHelp;
72
73 recvData >> count;
74
75 for (uint32 i = 0; i < count; i++)
76 {
77 uint32 time;
78 recvData >> time;
79 times.push_back(time);
80 }
81
82 recvData >> decompressedSize;
83
84 if (count && decompressedSize && decompressedSize < 0xFFFF)
85 {
86 uint32 pos = recvData.rpos();
87 ByteBuffer dest;
88 dest.resize(decompressedSize);
89
90 uLongf realSize = decompressedSize;
91 if (uncompress(dest.contents(), &realSize, recvData.contents() + pos, recvData.size() - pos) == Z_OK)
92 {
93 dest >> chatLog;
94 }
95 else
96 {
97 LOG_ERROR("network.opcode", "CMSG_GMTICKET_CREATE possibly corrupt. Uncompression failed.");
98 recvData.rfinish();
99 return;
100 }
101
102 recvData.rfinish(); // Will still have compressed data in buffer.
103 }
104
105 if (!chatLog.empty() && !ValidateHyperlinksAndMaybeKick(chatLog))
106 {
107 return;
108 }
109
110 ticket = new GmTicket(GetPlayer());
111 ticket->SetPosition(mapId, x, y, z);
112 ticket->SetMessage(message);
113 ticket->SetGmAction(needResponse, needMoreHelp);
114
115 if (!chatLog.empty())
116 ticket->SetChatLog(times, chatLog);
117
118 sTicketMgr->AddTicket(ticket);
119 sTicketMgr->UpdateLastChange();
120
121 sWorld->SendGMText(LANG_COMMAND_TICKETNEW, GetPlayer()->GetName().c_str(), ticket->GetId());
122
124 }
125
127 data << uint32(response);
128 SendPacket(&data);
129}
@ LANG_TICKET_REQ
Definition: Language.h:1158
@ LANG_COMMAND_TICKETNEW
Definition: Language.h:1020
@ GMTICKET_QUEUE_STATUS_DISABLED
Definition: TicketMgr.h:30
GMTicketResponse
Definition: TicketMgr.h:41
@ GMTICKET_RESPONSE_CREATE_ERROR
Definition: TicketMgr.h:44
@ GMTICKET_RESPONSE_CREATE_SUCCESS
Definition: TicketMgr.h:43
@ CONFIG_TICKET_LEVEL_REQ
Definition: IWorld.h:290
@ SMSG_GMTICKET_CREATE
Definition: Opcodes.h:548
bool IsClosed() const
Definition: TicketMgr.h:94
void SetPosition(uint32 mapId, float x, float y, float z)
Definition: TicketMgr.cpp:223
void SetMessage(std::string const &message)
Definition: TicketMgr.cpp:256
void SetGmAction(uint32 needResponse, bool needMoreHelp)
Definition: TicketMgr.cpp:231
bool IsCompleted() const
Definition: TicketMgr.h:95
uint32 GetId() const
Definition: TicketMgr.h:101
void SetChatLog(std::list< uint32 > time, std::string const &log)
Definition: TicketMgr.cpp:242
void resize(size_t newsize)
Definition: ByteBuffer.h:447
uint8 * contents()
Definition: ByteBuffer.h:424

◆ HandleGMTicketDeleteOpcode()

void WorldSession::HandleGMTicketDeleteOpcode ( WorldPacket recvPacket)

Definition at line 158 of file TicketHandler.cpp.

159{
160 if (GmTicket* ticket = sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID()))
161 {
164 SendPacket(&data);
165
166 sWorld->SendGMText(LANG_COMMAND_TICKETPLAYERABANDON, GetPlayer()->GetName().c_str(), ticket->GetId());
167
168 sTicketMgr->CloseTicket(ticket->GetId(), GetPlayer()->GetGUID());
169 sTicketMgr->SendTicket(this, nullptr);
170 }
171}
@ LANG_COMMAND_TICKETPLAYERABANDON
Definition: Language.h:1022

◆ HandleGMTicketGetTicketOpcode()

void WorldSession::HandleGMTicketGetTicketOpcode ( WorldPacket recvPacket)

Definition at line 173 of file TicketHandler.cpp.

174{
176
177 if (GmTicket* ticket = sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID()))
178 {
179 if (ticket->IsCompleted())
180 ticket->SendResponse(this);
181 else
182 sTicketMgr->SendTicket(this, ticket);
183 }
184 else
185 sTicketMgr->SendTicket(this, nullptr);
186}
void SendQueryTimeResponse()

◆ HandleGMTicketSystemStatusOpcode()

void WorldSession::HandleGMTicketSystemStatusOpcode ( WorldPacket recvPacket)

Definition at line 188 of file TicketHandler.cpp.

189{
190 // Note: This only disables the ticket UI at client side and is not fully reliable
191 // are we sure this is a uint32? Should ask Zor
194 SendPacket(&data);
195}
@ GMTICKET_QUEUE_STATUS_ENABLED
Definition: TicketMgr.h:31
@ SMSG_GMTICKET_SYSTEMSTATUS
Definition: Opcodes.h:569

◆ HandleGMTicketUpdateOpcode()

void WorldSession::HandleGMTicketUpdateOpcode ( WorldPacket recvPacket)

Definition at line 131 of file TicketHandler.cpp.

132{
133 std::string message;
134 recv_data >> message;
135
136 if (!ValidateHyperlinksAndMaybeKick(message))
137 {
138 return;
139 }
140
142 if (GmTicket* ticket = sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID()))
143 {
145 ticket->SetMessage(message);
146 ticket->SaveToDB(trans);
147
148 sWorld->SendGMText(LANG_COMMAND_TICKETUPDATED, GetPlayer()->GetName().c_str(), ticket->GetId());
149
151 }
152
154 data << uint32(response);
155 SendPacket(&data);
156}
@ LANG_COMMAND_TICKETUPDATED
Definition: Language.h:1021
@ GMTICKET_RESPONSE_UPDATE_SUCCESS
Definition: TicketMgr.h:45
@ GMTICKET_RESPONSE_UPDATE_ERROR
Definition: TicketMgr.h:46
@ SMSG_GMTICKET_UPDATETEXT
Definition: Opcodes.h:550

◆ HandleGossipHelloOpcode()

void WorldSession::HandleGossipHelloOpcode ( WorldPacket recvPacket)

Definition at line 274 of file NPCHandler.cpp.

275{
276 LOG_DEBUG("network", "WORLD: Received CMSG_GOSSIP_HELLO");
277
278 ObjectGuid guid;
279 recvData >> guid;
280
282 if (!unit)
283 {
284 LOG_DEBUG("network", "WORLD: HandleGossipHelloOpcode - Unit ({}) not found or you can not interact with him.", guid.ToString());
285 return;
286 }
287
288 // xinef: check if we have ANY npc flags
289 if (unit->GetNpcFlags() == UNIT_NPC_FLAG_NONE)
290 return;
291
292 // xinef: do not allow to open gossip when npc is in combat
293 if (unit->GetNpcFlags() == UNIT_NPC_FLAG_GOSSIP && unit->IsInCombat()) // should work on all flags?
294 return;
295
296 // set faction visible if needed
297 if (FactionTemplateEntry const* factionTemplateEntry = sFactionTemplateStore.LookupEntry(unit->GetFaction()))
298 _player->GetReputationMgr().SetVisible(factionTemplateEntry);
299
301 // remove fake death
302 //if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
303 // GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
304
305 // Stop the npc if moving
307 unit->PauseMovement(pause);
308 unit->SetHomePosition(unit->GetPosition());
309
310 // If spiritguide, no need for gossip menu, just put player into resurrect queue
311 if (unit->IsSpiritGuide())
312 {
314 if (bg)
315 {
317 sBattlegroundMgr->SendAreaSpiritHealerQueryOpcode(_player, bg, unit->GetGUID());
318 return;
319 }
320 }
321
322 if (!sScriptMgr->OnGossipHello(_player, unit))
323 {
324 // _player->TalkedToCreature(unit->GetEntry(), unit->GetGUID());
327 }
328 unit->AI()->sGossipHello(_player);
329}
DBCStorage< FactionTemplateEntry > sFactionTemplateStore(FactionTemplateEntryfmt)
@ UNIT_NPC_FLAG_GOSSIP
Definition: Unit.h:516
@ UNIT_NPC_FLAG_NONE
Definition: Unit.h:515
@ AURA_INTERRUPT_FLAG_TALK
Definition: SpellDefines.h:54
virtual void sGossipHello(Player *)
Definition: UnitAI.h:341
CreatureTemplate const * GetCreatureTemplate() const
Definition: Creature.h:196
CreatureAI * AI() const
Definition: Creature.h:134
void SendPreparedGossip(WorldObject *source)
void PrepareGossipMenu(WorldObject *source, uint32 menuId=0, bool showQuests=false)
ReputationMgr & GetReputationMgr()
Definition: Player.h:2075
NPCFlags GetNpcFlags() const
Definition: Unit.h:1642
void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except=0, bool isAutoshot=false)
Definition: Unit.cpp:5084
bool IsSpiritGuide() const
Definition: Unit.h:1658
void SetVisible(FactionTemplateEntry const *factionTemplateEntry)

◆ HandleGossipSelectOptionOpcode()

void WorldSession::HandleGossipSelectOptionOpcode ( WorldPacket recvPacket)

Definition at line 87 of file MiscHandler.cpp.

88{
89 LOG_DEBUG("network", "WORLD: CMSG_GOSSIP_SELECT_OPTION");
90
91 uint32 gossipListId;
92 uint32 menuId;
93 ObjectGuid guid;
94 std::string code = "";
95
96 recv_data >> guid >> menuId >> gossipListId;
97
99 recv_data >> code;
100
101 // Prevent cheating on C++ scripted menus
103 {
104 return;
105 }
106
107 Creature* unit = nullptr;
108 GameObject* go = nullptr;
109 Item* item = nullptr;
110 if (guid.IsCreatureOrVehicle())
111 {
113 if (!unit)
114 {
115 LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - Unit ({}) not found or you can't interact with him.", guid.ToString());
116 return;
117 }
118 }
119 else if (guid.IsGameObject())
120 {
121 go = _player->GetMap()->GetGameObject(guid);
122 if (!go)
123 {
124 LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - GameObject ({}) not found.", guid.ToString());
125 return;
126 }
127 }
128 else if (guid.IsItem())
129 {
130 item = _player->GetItemByGuid(guid);
131 if (!item || _player->IsBankPos(item->GetPos()))
132 {
133 //LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - {} not found.", guid.ToString());
134 return;
135 }
136 }
137 else if (guid.IsPlayer())
138 {
139 if (guid != _player->GetGUID() || menuId != _player->PlayerTalkClass->GetGossipMenu().GetMenuId())
140 {
141 //LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - {} not found.", guid.ToString());
142 return;
143 }
144 }
145 else
146 {
147 LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - unsupported GUID type for {}.", guid.ToString());
148 return;
149 }
150
151 // remove fake death
152 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
154
155 if ((unit && unit->GetScriptId() != unit->LastUsedScriptID) || (go && go->GetScriptId() != go->LastUsedScriptID))
156 {
157 LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - Script reloaded while in use, ignoring and set new scipt id");
158 if (unit)
159 unit->LastUsedScriptID = unit->GetScriptId();
160 if (go)
161 go->LastUsedScriptID = go->GetScriptId();
163 return;
164 }
165 if (!code.empty())
166 {
167 if (unit)
168 {
169 unit->AI()->sGossipSelectCode(_player, menuId, gossipListId, code.c_str());
170 if (!sScriptMgr->OnGossipSelectCode(_player, unit, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId), code.c_str()))
171 _player->OnGossipSelect(unit, gossipListId, menuId);
172 }
173 else if (go)
174 {
175 go->AI()->GossipSelectCode(_player, menuId, gossipListId, code.c_str());
176 sScriptMgr->OnGossipSelectCode(_player, go, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId), code.c_str());
177 }
178 else if (item)
179 {
180 sScriptMgr->OnGossipSelectCode(_player, item, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId), code.c_str());
181 }
182 else
183 {
184 sScriptMgr->OnGossipSelectCode(_player, menuId, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId), code.c_str());
185 }
186 }
187 else
188 {
189 if (unit)
190 {
191 unit->AI()->sGossipSelect(_player, menuId, gossipListId);
192 if (!sScriptMgr->OnGossipSelect(_player, unit, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId)))
193 _player->OnGossipSelect(unit, gossipListId, menuId);
194 }
195 else if (go)
196 {
197 go->AI()->GossipSelect(_player, menuId, gossipListId);
198 if (!sScriptMgr->OnGossipSelect(_player, go, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId)))
199 _player->OnGossipSelect(go, gossipListId, menuId);
200 }
201 else if (item)
202 {
203 sScriptMgr->OnGossipSelect(_player, item, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId));
204 }
205 else
206 {
207 sScriptMgr->OnGossipSelect(_player, menuId, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId));
208 }
209 }
210}
virtual bool GossipSelectCode(Player *, uint32, uint32, char const *)
Definition: GameObjectAI.h:56
virtual bool GossipSelect(Player *, uint32, uint32)
Definition: GameObjectAI.h:55
virtual void sGossipSelectCode(Player *, uint32, uint32, char const *)
Definition: UnitAI.h:343
virtual void sGossipSelect(Player *, uint32, uint32)
Definition: UnitAI.h:342
uint32 GetScriptId() const
Definition: Creature.cpp:2919
uint32 GetMenuId() const
Definition: GossipDef.h:171
ObjectGuid GetSenderGUID() const
Definition: GossipDef.h:217
void SendCloseGossip()
Definition: GossipDef.cpp:240
bool IsGossipOptionCoded(uint32 selection) const
Definition: GossipDef.h:271
uint32 GetGossipOptionSender(uint32 selection) const
Definition: GossipDef.h:269
GossipMenu & GetGossipMenu()
Definition: GossipDef.h:263
uint32 GetGossipOptionAction(uint32 selection) const
Definition: GossipDef.h:270
virtual uint32 GetScriptId() const
uint32 LastUsedScriptID
Definition: Object.h:582
bool IsCreatureOrVehicle() const
Definition: ObjectGuid.h:168
void OnGossipSelect(WorldObject *source, uint32 gossipListId, uint32 menuId)
PlayerMenu * PlayerTalkClass
Definition: Player.h:2187

◆ HandleGrantLevel()

void WorldSession::HandleGrantLevel ( WorldPacket recvData)

Definition at line 23 of file ReferAFriendHandler.cpp.

24{
25 LOG_DEBUG("network", "WORLD: CMSG_GRANT_LEVEL");
26
27 ObjectGuid guid;
28 recvData >> guid.ReadAsPacked();
29
31
32 // check cheating
34 uint8 error = 0;
35 if (!target)
37 else if (levels == 0)
39 else if (GetRecruiterId() != target->GetSession()->GetAccountId())
41 else if (target->GetTeamId() != _player->GetTeamId())
43 else if (target->getLevel() >= _player->getLevel())
45 else if (target->getLevel() >= sWorld->getIntConfig(CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL))
47 else if (target->GetGroup() != _player->GetGroup())
49
50 if (error)
51 {
53 data << uint32(error);
55 data << target->GetName();
56
57 SendPacket(&data);
58 return;
59 }
60
62 data2 << _player->GetPackGUID();
63 target->GetSession()->SendPacket(&data2);
64}
@ ERR_REFER_A_FRIEND_TARGET_TOO_HIGH
Definition: Player.h:960
@ ERR_REFER_A_FRIEND_DIFFERENT_FACTION
Definition: Player.h:963
@ ERR_REFER_A_FRIEND_NO_TARGET
Definition: Player.h:966
@ ERR_REFER_A_FRIEND_INSUFFICIENT_GRANTABLE_LEVELS
Definition: Player.h:961
@ ERR_REFER_A_FRIEND_NOT_REFERRED_BY
Definition: Player.h:959
@ ERR_REFER_A_FRIEND_NOT_IN_GROUP
Definition: Player.h:967
@ ERR_REFER_A_FRIEND_GRANT_LEVEL_MAX_I
Definition: Player.h:965
@ CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL
Definition: IWorld.h:240
@ SMSG_REFER_A_FRIEND_FAILURE
Definition: Opcodes.h:1087
@ SMSG_PROPOSE_LEVEL_GRANT
Definition: Opcodes.h:1085

◆ HandleGroupAcceptOpcode()

void WorldSession::HandleGroupAcceptOpcode ( WorldPacket recvPacket)

Definition at line 230 of file GroupHandler.cpp.

231{
232 LOG_DEBUG("network", "WORLD: Received CMSG_GROUP_ACCEPT");
233
234 recvData.read_skip<uint32>();
235 Group* group = GetPlayer()->GetGroupInvite();
236
237 if (!group)
238 return;
239
240 // Remove player from invitees in any case
241 group->RemoveInvite(GetPlayer());
242
243 if (GetPlayer()->IsSpectator())
244 {
246 return;
247 }
248
249 if (!sScriptMgr->CanGroupAccept(GetPlayer(), group))
250 return;
251
252 if (group->GetLeaderGUID() == GetPlayer()->GetGUID())
253 {
254 LOG_ERROR("network.opcode", "HandleGroupAcceptOpcode: player {} ({}) tried to accept an invite to his own group",
255 GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString());
256 return;
257 }
258
259 // Group is full
260 if (group->IsFull())
261 {
263 return;
264 }
265
266 Player* leader = ObjectAccessor::FindConnectedPlayer(group->GetLeaderGUID());
267
268 // Forming a new group, create it
269 if (!group->IsCreated())
270 {
271 // This can happen if the leader is zoning. To be removed once delayed actions for zoning are implemented
272 if (!leader || leader->IsSpectator())
273 {
274 group->RemoveAllInvites();
275 return;
276 }
277
278 // If we're about to create a group there really should be a leader present
279 ASSERT(leader);
280 group->RemoveInvite(leader);
281 group->Create(leader);
282 sGroupMgr->AddGroup(group);
283 }
284
285 // Everything is fine, do it, PLAYER'S GROUP IS SET IN ADDMEMBER!!!
286 if (!group->AddMember(GetPlayer()))
287 return;
288
289 group->BroadcastGroupUpdate();
290}
#define sGroupMgr
Definition: GroupMgr.h:51
@ ERR_INVITE_RESTRICTED
@ ERR_GROUP_FULL
@ PARTY_OP_INVITE
Definition: WorldSession.h:191
bool IsSpectator() const
Definition: Player.h:2521
Group * GetGroupInvite()
Definition: Player.h:2415
void RemoveInvite(Player *player)
Definition: Group.cpp:351
void SendPartyResult(PartyOperation operation, std::string const &member, PartyResult res, uint32 val=0)

◆ HandleGroupAssistantLeaderOpcode()

void WorldSession::HandleGroupAssistantLeaderOpcode ( WorldPacket recvData)

Definition at line 678 of file GroupHandler.cpp.

679{
680 LOG_DEBUG("network", "WORLD: Received CMSG_GROUP_ASSISTANT_LEADER");
681
682 Group* group = GetPlayer()->GetGroup();
683 if (!group)
684 return;
685
686 if (!group->IsLeader(GetPlayer()->GetGUID()))
687 return;
688
689 ObjectGuid guid;
690 bool apply;
691 recvData >> guid;
692 recvData >> apply;
693
694 group->SetGroupMemberFlag(guid, apply, MEMBER_FLAG_ASSISTANT);
695
696 group->SendUpdate();
697}
@ MEMBER_FLAG_ASSISTANT
Definition: Group.h:72
bool IsLeader(ObjectGuid guid) const
Definition: Group.cpp:2276
void SendUpdate()
Definition: Group.cpp:1633
void SetGroupMemberFlag(ObjectGuid guid, bool apply, GroupMemberFlags flag)
Definition: Group.cpp:2337

◆ HandleGroupChangeSubGroupOpcode()

void WorldSession::HandleGroupChangeSubGroupOpcode ( WorldPacket recvData)

Definition at line 639 of file GroupHandler.cpp.

640{
641 LOG_DEBUG("network", "WORLD: Received CMSG_GROUP_CHANGE_SUB_GROUP");
642
643 // we will get correct pointer for group here, so we don't have to check if group is BG raid
644 Group* group = GetPlayer()->GetGroup();
645 if (!group)
646 return;
647
648 std::string name;
649 uint8 groupNr;
650 recvData >> name;
651 recvData >> groupNr;
652
653 if (groupNr >= MAX_RAID_SUBGROUPS)
654 return;
655
656 ObjectGuid senderGuid = GetPlayer()->GetGUID();
657 if (!group->IsLeader(senderGuid) && !group->IsAssistant(senderGuid))
658 return;
659
660 if (!group->HasFreeSlotSubGroup(groupNr))
661 return;
662
663 Player* movedPlayer = ObjectAccessor::FindPlayerByName(name, false);
664 ObjectGuid guid;
665 if (movedPlayer)
666 {
667 guid = movedPlayer->GetGUID();
668 }
669 else
670 {
671 CharacterDatabase.EscapeString(name);
672 guid = sCharacterCache->GetCharacterGuidByName(name);
673 }
674
675 group->ChangeMembersGroup(guid, groupNr);
676}
#define MAX_RAID_SUBGROUPS
Definition: Group.h:44
void ChangeMembersGroup(ObjectGuid guid, uint8 group)
Definition: Group.cpp:1777
bool IsAssistant(ObjectGuid guid) const
Definition: Group.cpp:2290
bool HasFreeSlotSubGroup(uint8 subgroup) const
Definition: Group.cpp:2314

◆ HandleGroupDeclineOpcode()

void WorldSession::HandleGroupDeclineOpcode ( WorldPacket recvPacket)

Definition at line 292 of file GroupHandler.cpp.

293{
294 LOG_DEBUG("network", "WORLD: Received CMSG_GROUP_DECLINE");
295
296 Group* group = GetPlayer()->GetGroupInvite();
297 if (!group)
298 return;
299
300 // Remember leader if online (group pointer will be invalid if group gets disbanded)
302
303 // uninvite, group can be deleted
305
306 if (!leader)
307 return;
308
309 // report
310 WorldPacket data(SMSG_GROUP_DECLINE, GetPlayer()->GetName().length());
311 data << GetPlayer()->GetName();
312 leader->GetSession()->SendPacket(&data);
313}
@ SMSG_GROUP_DECLINE
Definition: Opcodes.h:146
void UninviteFromGroup()
Definition: Player.cpp:2283

◆ HandleGroupDisbandOpcode()

void WorldSession::HandleGroupDisbandOpcode ( WorldPacket recvPacket)

error handling

Definition at line 458 of file GroupHandler.cpp.

459{
460 LOG_DEBUG("network", "WORLD: Received CMSG_GROUP_DISBAND");
461
462 Group* grp = GetPlayer()->GetGroup();
463 if (!grp)
464 return;
465
466 if (_player->InBattleground())
467 {
469 return;
470 }
471
473 /********************/
474
475 // everything's fine, do it
477
479}
@ GROUP_REMOVEMETHOD_LEAVE
@ ERR_PARTY_RESULT_OK
@ PARTY_OP_LEAVE
Definition: WorldSession.h:193
static void RemoveFromGroup(Group *group, ObjectGuid guid, RemoveMethod method=GROUP_REMOVEMETHOD_DEFAULT, ObjectGuid kicker=ObjectGuid::Empty, const char *reason=nullptr)
Definition: Player.cpp:2307

◆ HandleGroupInviteOpcode()

void WorldSession::HandleGroupInviteOpcode ( WorldPacket recvPacket)

Definition at line 61 of file GroupHandler.cpp.

62{
63 LOG_DEBUG("network", "WORLD: Received CMSG_GROUP_INVITE");
64
65 std::string membername;
66 recvData >> membername;
67 recvData.read_skip<uint32>();
68
69 // attempt add selected player
70
71 // cheating
72 if (!normalizePlayerName(membername))
73 {
75 return;
76 }
77
78 Player* player = ObjectAccessor::FindPlayerByName(membername, false);
79
80 // no player or cheat self-invite
81 if (!player || player == GetPlayer())
82 {
84 return;
85 }
86
87 if (!sScriptMgr->CanGroupInvite(GetPlayer(), membername))
88 return;
89
90 if (GetPlayer()->IsSpectator() || player->IsSpectator())
91 {
93 return;
94 }
95
96 // restrict invite to GMs
97 if (!sWorld->getBoolConfig(CONFIG_ALLOW_GM_GROUP) && !GetPlayer()->IsGameMaster() && player->IsGameMaster())
98 {
100 return;
101 }
102
103 // can't group with
104 if (!GetPlayer()->IsGameMaster() && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && GetPlayer()->GetTeamId() != player->GetTeamId())
105 {
107 return;
108 }
109 if (GetPlayer()->GetInstanceId() != 0 && player->GetInstanceId() != 0 && GetPlayer()->GetInstanceId() != player->GetInstanceId() && GetPlayer()->GetMapId() == player->GetMapId())
110 {
112 return;
113 }
114 // just ignore us
115 if (player->GetInstanceId() != 0 && player->GetDungeonDifficulty() != GetPlayer()->GetDungeonDifficulty())
116 {
118 return;
119 }
120
121 if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUID()))
122 {
124 return;
125 }
126
127 if (!player->GetSocial()->HasFriend(GetPlayer()->GetGUID()) && GetPlayer()->getLevel() < sWorld->getIntConfig(CONFIG_PARTY_LEVEL_REQ))
128 {
130 return;
131 }
132
133 Group* group = GetPlayer()->GetGroup();
134 if (group)
135 {
136 if (group->isLFGGroup() && group->IsLfgRandomInstance())
137 {
139 return;
140 }
141
142 if (group->isBGGroup() || group->isBFGroup())
143 {
144 group = GetPlayer()->GetOriginalGroup();
145 }
146 }
147
148 Group* group2 = player->GetGroup();
149 if (group2 && (group2->isBGGroup() || group2->isBFGroup()))
150 group2 = player->GetOriginalGroup();
151 // player already in another group or invited
152 if (group2 || player->GetGroupInvite())
153 {
155
156 if (group2)
157 {
158 // tell the player that they were invited but it failed as they were already in a group
159 WorldPacket data(SMSG_GROUP_INVITE, 25); // guess size
160 data << uint8(0); // invited/already in group flag
161 data << GetPlayer()->GetName(); // max len 48
162 data << uint32(0); // unk
163 data << uint8(0); // count
164 data << uint32(0); // unk
165 player->GetSession()->SendPacket(&data);
166 }
167
168 return;
169 }
170
171 if (group)
172 {
173 // not have permissions for invite
174 if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
175 {
177 return;
178 }
179 // not have place
180 if (group->IsFull())
181 {
183 return;
184 }
185 }
186
187 // xinef: if player has no group, check group invite
188 if (!group && GetPlayer()->GetGroupInvite() && GetPlayer()->GetGroupInvite()->GetLeaderGUID() == GetPlayer()->GetGUID())
189 group = GetPlayer()->GetGroupInvite();
190
191 // ok, but group not exist, start a new group
192 // but don't create and save the group to the DB until
193 // at least one person joins
194 if (!group)
195 {
196 group = new Group;
197 // new group: if can't add then delete
198 if (!group->AddLeaderInvite(GetPlayer()))
199 {
200 delete group;
201 return;
202 }
203 if (!group->AddInvite(player))
204 {
205 delete group;
206 return;
207 }
208 }
209 else
210 {
211 // already existed group: if can't add then just leave
212 if (!group->AddInvite(player))
213 {
214 return;
215 }
216 }
217
218 // ok, we do it
219 WorldPacket data(SMSG_GROUP_INVITE, 10); // guess size
220 data << uint8(1); // invited/already in group flag
221 data << GetPlayer()->GetName(); // max len 48
222 data << uint32(0); // unk
223 data << uint8(0); // count
224 data << uint32(0); // unk
225 player->GetSession()->SendPacket(&data);
226
228}
@ CONFIG_PARTY_LEVEL_REQ
Definition: IWorld.h:287
@ CONFIG_ALLOW_GM_GROUP
Definition: IWorld.h:92
@ CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP
Definition: IWorld.h:80
@ ERR_ALREADY_IN_GROUP_S
@ ERR_TARGET_NOT_IN_INSTANCE_S
@ ERR_IGNORING_YOU_S
@ ERR_NOT_LEADER
@ ERR_PLAYER_WRONG_FACTION
@ ERR_BAD_PLAYER_NAME_S
@ SMSG_GROUP_INVITE
Definition: Opcodes.h:141
uint32 GetInstanceId() const
Definition: Object.h:431
Difficulty GetDungeonDifficulty() const
Definition: Player.h:1870
Group * GetOriginalGroup()
Definition: Player.h:2432
bool HasFriend(ObjectGuid friend_guid) const
Definition: SocialMgr.cpp:188
bool AddLeaderInvite(Player *player)
Definition: Group.cpp:341
bool isLFGGroup(bool restricted=false) const
Definition: Group.cpp:2205
bool IsLfgRandomInstance() const
Definition: Group.h:311
bool isBGGroup() const
Definition: Group.cpp:2216
bool isBFGroup() const
Definition: Group.cpp:2221
bool AddInvite(Player *player)
Definition: Group.cpp:320
bool IsFull() const
Definition: Group.cpp:2200

◆ HandleGroupRaidConvertOpcode()

void WorldSession::HandleGroupRaidConvertOpcode ( WorldPacket recvData)

error handling

Definition at line 612 of file GroupHandler.cpp.

613{
614 LOG_DEBUG("network", "WORLD: Received CMSG_GROUP_RAID_CONVERT");
615
616 Group* group = GetPlayer()->GetGroup();
617 if (!group)
618 return;
619
620 if (_player->InBattleground())
621 return;
622
624 if (group->CheckLevelForRaid())
625 {
627 return;
628 }
629
630 if (!group->IsLeader(GetPlayer()->GetGUID()) || group->GetMembersCount() < 2 || group->isLFGGroup()) // pussywizard: not allowed for lfg groups, it is either raid from the beginning or not!
631 return;
632 /********************/
633
634 // everything's fine, do it (is it 0 (PARTY_OP_INVITE) correct code)
636 group->ConvertToRaid();
637}
@ ERR_RAID_DISALLOWED_BY_LEVEL
bool CheckLevelForRaid()
Definition: Group.cpp:282
void ConvertToRaid()
Definition: Group.cpp:292

◆ HandleGroupSetLeaderOpcode()

void WorldSession::HandleGroupSetLeaderOpcode ( WorldPacket recvPacket)

Definition at line 437 of file GroupHandler.cpp.

438{
439 LOG_DEBUG("network", "WORLD: Received CMSG_GROUP_SET_LEADER");
440
441 ObjectGuid guid;
442 recvData >> guid;
443
445 Group* group = GetPlayer()->GetGroup();
446
447 if (!group || !player)
448 return;
449
450 if (!group->IsLeader(GetPlayer()->GetGUID()) || player->GetGroup() != group || guid == GetPlayer()->GetGUID())
451 return;
452
453 // Everything's fine, accepted.
454 group->ChangeLeader(guid);
455 group->SendUpdate();
456}
void ChangeLeader(ObjectGuid guid)
Definition: Group.cpp:712

◆ HandleGroupSwapSubGroupOpcode()

void WorldSession::HandleGroupSwapSubGroupOpcode ( WorldPacket recvData)

Definition at line 1131 of file GroupHandler.cpp.

1132{
1133 std::string playerName1, playerName2;
1134
1135 // first = moved from, second = moved to
1136 recv_data >> playerName1;
1137 recv_data >> playerName2;
1138
1139 if (!normalizePlayerName(playerName1))
1140 {
1142 return;
1143 }
1144 if (!normalizePlayerName(playerName2))
1145 {
1147 return;
1148 }
1149
1150 Group* group = GetPlayer()->GetGroup();
1151 if (!group || !group->isRaidGroup())
1152 {
1153 return;
1154 }
1155
1156 if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
1157 {
1158 return;
1159 }
1160
1161 //get guid, member may be offline
1162 auto getGuid = [&group](std::string const& playerName)
1163 {
1164 // no player, cheating?
1165 if (!group->GetMemberGUID(playerName))
1166 {
1167 return ObjectGuid::Empty;
1168 }
1169
1170 if (Player* player = ObjectAccessor::FindPlayerByName(playerName.c_str()))
1171 {
1172 return player->GetGUID();
1173 }
1174 else
1175 {
1176 if (ObjectGuid guid = sCharacterCache->GetCharacterGuidByName(playerName))
1177 {
1178 return guid;
1179 }
1180 else
1181 {
1182 return ObjectGuid::Empty; // no player - again, cheating?
1183 }
1184 }
1185 };
1186
1187 ObjectGuid guid1 = getGuid(playerName1);
1188 ObjectGuid guid2 = getGuid(playerName2);
1189
1190 if(!guid1 || !guid2)
1191 {
1193 return;
1194 }
1195
1196 uint8 groupId1 = group->GetMemberGroup(guid1);
1197 uint8 groupId2 = group->GetMemberGroup(guid2);
1198
1199 if (groupId1 == MAX_RAID_SUBGROUPS + 1 || groupId2 == MAX_RAID_SUBGROUPS + 1)
1200 {
1201 return;
1202 }
1203
1204 if (groupId1 == groupId2)
1205 {
1206 return;
1207 }
1208
1209 group->ChangeMembersGroup(guid1, groupId2);
1210 group->ChangeMembersGroup(guid2, groupId1);
1211}
@ ERR_GROUP_SWAP_FAILED
@ PARTY_OP_SWAP
Definition: WorldSession.h:194
uint8 GetMemberGroup(ObjectGuid guid) const
Definition: Group.cpp:2319
ObjectGuid GetMemberGUID(const std::string &name)
Definition: Group.cpp:2281
bool isRaidGroup() const
Definition: Group.cpp:2211

◆ HandleGroupUninviteGuidOpcode()

void WorldSession::HandleGroupUninviteGuidOpcode ( WorldPacket recvPacket)

Definition at line 315 of file GroupHandler.cpp.

316{
317 LOG_DEBUG("network", "WORLD: Received CMSG_GROUP_UNINVITE_GUID");
318
319 ObjectGuid guid;
320 std::string reason, name;
321 recvData >> guid;
322 recvData >> reason;
323
324 //can't uninvite yourself
325 if (guid == GetPlayer()->GetGUID())
326 {
327 LOG_ERROR("network.opcode", "WorldSession::HandleGroupUninviteGuidOpcode: leader {} ({}) tried to uninvite himself from the group.",
328 GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString());
329 return;
330 }
331
332 sCharacterCache->GetCharacterNameByGuid(guid, name);
333
335 if (res != ERR_PARTY_RESULT_OK)
336 {
338 {
339 if (Player* kickTarget = ObjectAccessor::FindConnectedPlayer(guid))
340 {
341 if (Aura* dungeonCooldownAura = kickTarget->GetAura(lfg::LFG_SPELL_DUNGEON_COOLDOWN))
342 {
343 int32 elapsedTime = dungeonCooldownAura->GetMaxDuration() - dungeonCooldownAura->GetDuration();
344 if (static_cast<int32>(sWorld->getIntConfig(CONFIG_LFG_KICK_PREVENTION_TIMER)) > elapsedTime)
345 {
346 SendPartyResult(PARTY_OP_UNINVITE, name, res, (sWorld->getIntConfig(CONFIG_LFG_KICK_PREVENTION_TIMER) - elapsedTime) / 1000);
347 }
348 }
349 }
350 } else
351 {
353 }
354
355 return;
356 }
357
358 Group* grp = GetPlayer()->GetGroup();
359 if (!grp)
360 return;
361
362 // Xinef: do not allow to kick with empty reason, this will resend packet with given reason
363 if (grp->isLFGGroup(true) && reason.empty())
364 {
366 return;
367 }
368
369 if (grp->IsLeader(guid) && !grp->isLFGGroup(true))
370 {
372 return;
373 }
374
375 if (grp->IsMember(guid))
376 {
377 Player::RemoveFromGroup(grp, guid, GROUP_REMOVEMETHOD_KICK, GetPlayer()->GetGUID(), reason.c_str());
378 return;
379 }
380
381 if (Player* player = grp->GetInvited(guid))
382 {
383 player->UninviteFromGroup();
384 return;
385 }
386
388}
@ CONFIG_LFG_KICK_PREVENTION_TIMER
Definition: IWorld.h:407
@ GROUP_REMOVEMETHOD_KICK
PartyResult
@ ERR_PARTY_LFG_BOOT_NOT_ELIGIBLE_S
@ ERR_VOTE_KICK_REASON_NEEDED
@ ERR_TARGET_NOT_IN_GROUP_S
@ PARTY_OP_UNINVITE
Definition: WorldSession.h:192
@ LFG_SPELL_DUNGEON_COOLDOWN
Definition: LFGMgr.h:52
PartyResult CanUninviteFromGroup(ObjectGuid targetPlayerGUID=ObjectGuid::Empty) const
Definition: Player.cpp:12719
Player * GetInvited(ObjectGuid guid) const
Definition: Group.cpp:370
bool IsMember(ObjectGuid guid) const
Definition: Group.cpp:2271

◆ HandleGroupUninviteOpcode()

void WorldSession::HandleGroupUninviteOpcode ( WorldPacket recvPacket)

Definition at line 390 of file GroupHandler.cpp.

391{
392 LOG_DEBUG("network", "WORLD: Received CMSG_GROUP_UNINVITE");
393
394 std::string membername;
395 recvData >> membername;
396
397 // player not found
398 if (!normalizePlayerName(membername))
399 return;
400
401 // can't uninvite yourself
402 if (GetPlayer()->GetName() == membername)
403 {
404 LOG_ERROR("network.opcode", "WorldSession::HandleGroupUninviteOpcode: leader {} ({}) tried to uninvite himself from the group.",
405 GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString());
406 return;
407 }
408
409 Group* grp = GetPlayer()->GetGroup();
410 if (!grp)
411 {
412 return;
413 }
414
415 PartyResult res = GetPlayer()->CanUninviteFromGroup(grp->GetMemberGUID(membername));
416 if (res != ERR_PARTY_RESULT_OK)
417 {
419 return;
420 }
421
422 if (ObjectGuid guid = grp->GetMemberGUID(membername))
423 {
425 return;
426 }
427
428 if (Player* player = grp->GetInvited(membername))
429 {
430 player->UninviteFromGroup();
431 return;
432 }
433
435}

◆ HandleGuildAcceptOpcode()

void WorldSession::HandleGuildAcceptOpcode ( WorldPackets::Guild::AcceptGuildInvite invite)

Definition at line 61 of file GuildHandler.cpp.

62{
63 LOG_DEBUG("guild", "CMSG_GUILD_ACCEPT [{}]", GetPlayer()->GetName());
64
65 if (!GetPlayer()->GetGuildId())
66 if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildIdInvited()))
67 guild->HandleAcceptMember(this);
68}

◆ HandleGuildAddRankOpcode()

void WorldSession::HandleGuildAddRankOpcode ( WorldPackets::Guild::GuildAddRank packet)

Definition at line 203 of file GuildHandler.cpp.

204{
205 LOG_DEBUG("guild", "CMSG_GUILD_ADD_RANK [{}]: Rank: {}", GetPlayerInfo(), packet.Name);
206
207 if (Guild* guild = GetPlayer()->GetGuild())
208 guild->HandleAddNewRank(this, packet.Name);
209}
String< 15, Strings::NoHyperlinks > Name
Definition: GuildPackets.h:291

◆ HandleGuildBankBuyTab()

void WorldSession::HandleGuildBankBuyTab ( WorldPackets::Guild::GuildBankBuyTab packet)

Definition at line 363 of file GuildHandler.cpp.

364{
365 LOG_DEBUG("guild", "CMSG_GUILD_BANK_BUY_TAB [{}]: [{}[, TabId: {}", GetPlayerInfo(), packet.Banker .ToString(), packet.BankTab);
366
367 if (GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK))
368 if (Guild* guild = GetPlayer()->GetGuild())
369 guild->HandleBuyBankTab(this, packet.BankTab);
370}
@ GAMEOBJECT_TYPE_GUILD_BANK

◆ HandleGuildBankDepositMoney()

void WorldSession::HandleGuildBankDepositMoney ( WorldPackets::Guild::GuildBankDepositMoney packet)

Definition at line 304 of file GuildHandler.cpp.

305{
306 LOG_DEBUG("guild", "CMSG_GUILD_BANK_DEPOSIT_MONEY [{}]: Go: [{}], money: {}",
307 GetPlayerInfo(), packet.Banker.ToString(), packet.Money);
308
309 if (GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK))
310 if (packet.Money && GetPlayer()->HasEnoughMoney(packet.Money))
311 if (Guild* guild = GetPlayer()->GetGuild())
312 guild->HandleMemberDepositMoney(this, packet.Money);
313}

◆ HandleGuildBankerActivate()

void WorldSession::HandleGuildBankerActivate ( WorldPackets::Guild::GuildBankActivate packet)

Definition at line 274 of file GuildHandler.cpp.

275{
276 LOG_DEBUG("guild", "CMSG_GUILD_BANKER_ACTIVATE [{}]: Go: [{}] AllSlots: {}"
277 , GetPlayerInfo(), packet.Banker.ToString(), packet.FullUpdate);
278
280 if (!go)
281 return;
282
283 Guild* const guild = GetPlayer()->GetGuild();
284 if (!guild)
285 {
287 return;
288 }
289
290 guild->SendBankTabsInfo(this, packet.FullUpdate);
291}
@ GUILD_COMMAND_VIEW_TAB
Definition: Guild.h:115
@ ERR_GUILD_PLAYER_NOT_IN_GUILD
Definition: Guild.h:132
Guild * GetGuild() const
Definition: Player.cpp:15694
void SendBankTabsInfo(WorldSession *session, bool showTabs=false) const
Definition: Guild.cpp:1801
static void SendCommandResult(WorldSession *session, GuildCommandType type, GuildCommandError errCode, std::string_view param={})
Definition: Guild.cpp:115

◆ HandleGuildBankLogQuery()

void WorldSession::HandleGuildBankLogQuery ( WorldPackets::Guild::GuildBankLogQuery packet)

Definition at line 383 of file GuildHandler.cpp.

384{
385 LOG_DEBUG("guild", "MSG_GUILD_BANK_LOG_QUERY [{}]: TabId: {}", GetPlayerInfo(), packet.Tab);
386
387 if (Guild* guild = GetPlayer()->GetGuild())
388 guild->SendBankLog(this, packet.Tab);
389}

◆ HandleGuildBankMoneyWithdrawn()

void WorldSession::HandleGuildBankMoneyWithdrawn ( WorldPackets::Guild::GuildBankRemainingWithdrawMoneyQuery packet)

Definition at line 259 of file GuildHandler.cpp.

260{
261 LOG_DEBUG("guild", "MSG_GUILD_BANK_MONEY_WITHDRAWN [{}]", GetPlayerInfo());
262
263 if (Guild* guild = GetPlayer()->GetGuild())
264 guild->SendMoneyInfo(this);
265}

◆ HandleGuildBankQueryTab()

void WorldSession::HandleGuildBankQueryTab ( WorldPackets::Guild::GuildBankQueryTab packet)

Definition at line 294 of file GuildHandler.cpp.

295{
296 LOG_DEBUG("guild", "CMSG_GUILD_BANK_QUERY_TAB [{}]: Go: [{}], TabId: {}, ShowTabs: {}"
297 , GetPlayerInfo(), packet.Banker.ToString(), packet.Tab, packet.FullUpdate);
298
299 if (GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK))
300 if (Guild* guild = GetPlayer()->GetGuild())
301 guild->SendBankTabData(this, packet.Tab, packet.FullUpdate);
302}

◆ HandleGuildBankSwapItems()

void WorldSession::HandleGuildBankSwapItems ( WorldPackets::Guild::GuildBankSwapItems packet)

Definition at line 324 of file GuildHandler.cpp.

325{
326 if (!GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK))
327 {
328 return;
329 }
330
331 Guild* guild = GetPlayer()->GetGuild();
332 if (!guild)
333 {
334 return;
335 }
336
337 if (packet.BankOnly)
338 guild->SwapItems(GetPlayer(), packet.BankTab1, packet.BankSlot1, packet.BankTab, packet.BankSlot, packet.BankItemCount);
339 else
340 {
341 uint8 playerBag = NULL_BAG;
342 uint8 playerSlotId = NULL_SLOT;
343 uint8 toChar = 1;
344 uint32 splitedAmount = 0;
345
346 if (!packet.AutoStore)
347 {
348 playerBag = packet.ContainerSlot;
349 playerSlotId = packet.ContainerItemSlot;
350 toChar = packet.ToSlot;
351 splitedAmount = packet.StackCount;
352 }
353
354 // Player <-> Bank
355 // Allow to work with inventory only
356 if (!Player::IsInventoryPos(playerBag, playerSlotId) && !(playerBag == NULL_BAG && playerSlotId == NULL_SLOT))
358 else
359 guild->SwapItemsWithInventory(GetPlayer(), toChar != 0, packet.BankTab, packet.BankSlot, playerBag, playerSlotId, splitedAmount);
360 }
361}
void SwapItemsWithInventory(Player *player, bool toChar, uint8 tabId, uint8 slotId, uint8 playerBag, uint8 playerSlotId, uint32 splitedAmount)
Definition: Guild.cpp:2332
void SwapItems(Player *player, uint8 tabId, uint8 slotId, uint8 destTabId, uint8 destSlotId, uint32 splitedAmount)
Definition: Guild.cpp:2318

◆ HandleGuildBankUpdateTab()

void WorldSession::HandleGuildBankUpdateTab ( WorldPackets::Guild::GuildBankUpdateTab packet)

Definition at line 372 of file GuildHandler.cpp.

373{
374 LOG_DEBUG("guild", "CMSG_GUILD_BANK_UPDATE_TAB [{}]: Go: [{}], TabId: {}, Name: {}, Icon: {}"
375 , GetPlayerInfo(), packet.Banker.ToString(), packet.BankTab, packet.Name, packet.Icon);
376
377 if (!packet.Name.empty() && !packet.Icon.empty())
378 if (GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK))
379 if (Guild* guild = GetPlayer()->GetGuild())
380 guild->HandleSetBankTabInfo(this, packet.BankTab, packet.Name, packet.Icon);
381}
String< 16, Strings::NoHyperlinks > Name
Definition: GuildPackets.h:400

◆ HandleGuildBankWithdrawMoney()

void WorldSession::HandleGuildBankWithdrawMoney ( WorldPackets::Guild::GuildBankWithdrawMoney packet)

Definition at line 315 of file GuildHandler.cpp.

316{
317 LOG_DEBUG("guild", "CMSG_GUILD_BANK_WITHDRAW_MONEY [{}]: Go: [{}], money: {}",
318 GetPlayerInfo(), packet.Banker.ToString(), packet.Money);
319 if (packet.Money && GetPlayer()->GetGameObjectIfCanInteractWith(packet.Banker, GAMEOBJECT_TYPE_GUILD_BANK))
320 if (Guild* guild = GetPlayer()->GetGuild())
321 guild->HandleMemberWithdrawMoney(this, packet.Money);
322}

◆ HandleGuildChangeInfoTextOpcode()

void WorldSession::HandleGuildChangeInfoTextOpcode ( WorldPackets::Guild::GuildUpdateInfoText packet)

Definition at line 219 of file GuildHandler.cpp.

220{
221 LOG_DEBUG("guild", "CMSG_GUILD_INFO_TEXT [{}]: {}", GetPlayerInfo(), packet.InfoText);
222
223 if (Guild* guild = GetPlayer()->GetGuild())
224 guild->HandleSetInfo(this, packet.InfoText);
225}
String< 500, Strings::NoHyperlinks > InfoText
Definition: GuildPackets.h:309

◆ HandleGuildCreateOpcode()

void WorldSession::HandleGuildCreateOpcode ( WorldPackets::Guild::GuildCreate packet)

Definition at line 39 of file GuildHandler.cpp.

40{
41 LOG_ERROR("network.opcode", "CMSG_GUILD_CREATE: Possible hacking-attempt: {} tried to create a guild [Name: {}] using cheats", GetPlayerInfo(), packet.GuildName);
42}

◆ HandleGuildDeclineOpcode()

void WorldSession::HandleGuildDeclineOpcode ( WorldPackets::Guild::GuildDeclineInvitation decline)

Definition at line 70 of file GuildHandler.cpp.

71{
72 LOG_DEBUG("guild", "CMSG_GUILD_DECLINE [{}]", GetPlayerInfo());
73
74 if (GetPlayer()->GetGuild())
75 {
76 return;
77 }
78
81}
void SetGuildIdInvited(uint32 GuildId)
Definition: Player.h:1849
void SetInGuild(uint32 GuildId)
Definition: Player.h:1841

◆ HandleGuildDelRankOpcode()

void WorldSession::HandleGuildDelRankOpcode ( WorldPackets::Guild::GuildDeleteRank packet)

Definition at line 211 of file GuildHandler.cpp.

212{
213 LOG_DEBUG("guild", "CMSG_GUILD_DEL_RANK [{}]", GetPlayerInfo());
214
215 if (Guild* guild = GetPlayer()->GetGuild())
216 guild->HandleRemoveLowestRank(this);
217}

◆ HandleGuildDemoteOpcode()

void WorldSession::HandleGuildDemoteOpcode ( WorldPackets::Guild::GuildDemoteMember demote)

Definition at line 110 of file GuildHandler.cpp.

111{
112 LOG_DEBUG("guild", "CMSG_GUILD_DEMOTE [{}]: Target: {}", GetPlayerInfo(), demote.Demotee);
113
114 if (normalizePlayerName(demote.Demotee))
115 if (Guild* guild = GetPlayer()->GetGuild())
116 guild->HandleUpdateMemberRank(this, demote.Demotee, true);
117}

◆ HandleGuildDisbandOpcode()

void WorldSession::HandleGuildDisbandOpcode ( WorldPackets::Guild::GuildDelete packet)

Definition at line 127 of file GuildHandler.cpp.

128{
129 LOG_DEBUG("guild", "CMSG_GUILD_DISBAND [{}]", GetPlayerInfo());
130
131 if (Guild* guild = GetPlayer()->GetGuild())
132 guild->HandleDisband(this);
133}

◆ HandleGuildEventLogQueryOpcode()

void WorldSession::HandleGuildEventLogQueryOpcode ( WorldPackets::Guild::GuildEventLogQuery packet)

Definition at line 251 of file GuildHandler.cpp.

252{
253 LOG_DEBUG("guild", "MSG_GUILD_EVENT_LOG_QUERY [{}]", GetPlayerInfo());
254
255 if (Guild* guild = GetPlayer()->GetGuild())
256 guild->SendEventLog(this);
257}

◆ HandleGuildInfoOpcode()

void WorldSession::HandleGuildInfoOpcode ( WorldPackets::Guild::GuildGetInfo packet)

Definition at line 83 of file GuildHandler.cpp.

84{
85 LOG_DEBUG("guild", "CMSG_GUILD_INFO [{}]", GetPlayerInfo());
86
87 if (Guild* guild = GetPlayer()->GetGuild())
88 guild->SendInfo(this);
89}

◆ HandleGuildInviteOpcode()

void WorldSession::HandleGuildInviteOpcode ( WorldPackets::Guild::GuildInviteByName packet)

Definition at line 44 of file GuildHandler.cpp.

45{
46 LOG_DEBUG("guild", "CMSG_GUILD_INVITE [{}]: Invited: {}", GetPlayerInfo(), packet.Name);
47 if (normalizePlayerName(packet.Name))
48 if (Guild* guild = GetPlayer()->GetGuild())
49 guild->HandleInviteMember(this, packet.Name);
50}

◆ HandleGuildLeaderOpcode()

void WorldSession::HandleGuildLeaderOpcode ( WorldPackets::Guild::GuildSetGuildMaster packet)

Definition at line 135 of file GuildHandler.cpp.

136{
137 LOG_DEBUG("guild", "CMSG_GUILD_LEADER [{}]: Target: {}", GetPlayerInfo(), packet.NewMasterName);
138
140 if (Guild* guild = GetPlayer()->GetGuild())
141 guild->HandleSetLeader(this, packet.NewMasterName);
142}

◆ HandleGuildLeaveOpcode()

void WorldSession::HandleGuildLeaveOpcode ( WorldPackets::Guild::GuildLeave leave)

Definition at line 119 of file GuildHandler.cpp.

120{
121 LOG_DEBUG("guild", "CMSG_GUILD_LEAVE [{}]", GetPlayerInfo());
122
123 if (Guild* guild = GetPlayer()->GetGuild())
124 guild->HandleLeaveMember(this);
125}

◆ HandleGuildMOTDOpcode()

void WorldSession::HandleGuildMOTDOpcode ( WorldPackets::Guild::GuildUpdateMotdText packet)

Definition at line 144 of file GuildHandler.cpp.

145{
146 LOG_DEBUG("guild", "CMSG_GUILD_MOTD [{}]: MOTD: {}", GetPlayerInfo(), packet.MotdText);
147
148 if (Guild* guild = GetPlayer()->GetGuild())
149 guild->HandleSetMOTD(this, packet.MotdText);
150}
String< 128, Strings::NoHyperlinks > MotdText
Definition: GuildPackets.h:150

◆ HandleGuildPermissions()

void WorldSession::HandleGuildPermissions ( WorldPackets::Guild::GuildPermissionsQuery packet)

Definition at line 267 of file GuildHandler.cpp.

268{
269 if (Guild* guild = GetPlayer()->GetGuild())
270 guild->SendPermissions(this);
271}

◆ HandleGuildPromoteOpcode()

void WorldSession::HandleGuildPromoteOpcode ( WorldPackets::Guild::GuildPromoteMember promote)

Definition at line 101 of file GuildHandler.cpp.

102{
103 LOG_DEBUG("guild", "CMSG_GUILD_PROMOTE [{}]: Target: {}", GetPlayerInfo(), promote.Promotee);
104
105 if (normalizePlayerName(promote.Promotee))
106 if (Guild* guild = GetPlayer()->GetGuild())
107 guild->HandleUpdateMemberRank(this, promote.Promotee, false);
108}

◆ HandleGuildQueryOpcode()

void WorldSession::HandleGuildQueryOpcode ( WorldPackets::Guild::QueryGuildInfo query)

Definition at line 29 of file GuildHandler.cpp.

30{
31 LOG_DEBUG("guild", "CMSG_GUILD_QUERY [{}]: Guild: {}", GetPlayerInfo(), query.GuildId);
32 if (!query.GuildId)
33 return;
34
35 if (Guild* guild = sGuildMgr->GetGuildById(query.GuildId))
36 guild->HandleQuery(this);
37}

◆ HandleGuildRankOpcode()

void WorldSession::HandleGuildRankOpcode ( WorldPackets::Guild::GuildSetRankPermissions packet)

Definition at line 171 of file GuildHandler.cpp.

172{
173 Guild* guild = GetPlayer()->GetGuild();
174 if (!guild)
175 {
176 return;
177 }
178
179 std::array<GuildBankRightsAndSlots, GUILD_BANK_MAX_TABS> rightsAndSlots;
180
181 for (uint8 tabId = 0; tabId < GUILD_BANK_MAX_TABS; ++tabId)
182 {
183 // For some reason the client is sending - 1 for guildmaster tab withdraw item limit, that's ilegal for us because we expect unsigned int.
184 // Probably core handling for this should be changed.
185 if (packet.TabWithdrawItemLimit[tabId] <= 0)
186 {
188 }
189 rightsAndSlots[tabId] = GuildBankRightsAndSlots(tabId, uint8(packet.TabFlags[tabId]), packet.TabWithdrawItemLimit[tabId]);
190 }
191
192 LOG_DEBUG("guild", "CMSG_GUILD_RANK [{}]: Rank: {} ({})", GetPlayerInfo(), packet.RankName, packet.RankID);
193
194 // Same as the issue above but this time with rights.
195 if (packet.Flags <= 0)
196 {
198 }
199
200 guild->HandleSetRankInfo(this, packet.RankID, packet.RankName, packet.Flags, packet.WithdrawGoldLimit, rightsAndSlots);
201}
@ GUILD_WITHDRAW_SLOT_UNLIMITED
Definition: Guild.h:52
@ GUILD_BANK_MAX_TABS
Definition: Guild.h:45
@ GUILD_BANK_RIGHT_FULL
Definition: Guild.h:195
void HandleSetRankInfo(WorldSession *session, uint8 rankId, std::string_view name, uint32 rights, uint32 moneyPerDay, std::array< GuildBankRightsAndSlots, GUILD_BANK_MAX_TABS > const &rightsAndSlots)
Definition: Guild.cpp:1378
String< 15, Strings::NoHyperlinks > RankName
Definition: GuildPackets.h:281
uint32 TabWithdrawItemLimit[GUILD_BANK_MAX_TABS]
Definition: GuildPackets.h:280
uint32 TabFlags[GUILD_BANK_MAX_TABS]
Definition: GuildPackets.h:279

◆ HandleGuildRemoveOpcode()

void WorldSession::HandleGuildRemoveOpcode ( WorldPackets::Guild::GuildOfficerRemoveMember packet)

Definition at line 52 of file GuildHandler.cpp.

53{
54 LOG_DEBUG("guild", "CMSG_GUILD_REMOVE [{}]: Target: {}", GetPlayerInfo(), packet.Removee);
55
56 if (normalizePlayerName(packet.Removee))
57 if (Guild* guild = GetPlayer()->GetGuild())
58 guild->HandleRemoveMember(this, packet.Removee);
59}

◆ HandleGuildRosterOpcode()

void WorldSession::HandleGuildRosterOpcode ( WorldPackets::Guild::GuildGetRoster packet)

Definition at line 91 of file GuildHandler.cpp.

92{
93 LOG_DEBUG("guild", "CMSG_GUILD_ROSTER [{}]", GetPlayerInfo());
94
95 if (Guild* guild = GetPlayer()->GetGuild())
96 guild->HandleRoster(this);
97 else
99}
@ GUILD_COMMAND_ROSTER
Definition: Guild.h:105

◆ HandleGuildSetOfficerNoteOpcode()

void WorldSession::HandleGuildSetOfficerNoteOpcode ( WorldPackets::Guild::GuildSetMemberNote packet)

Definition at line 161 of file GuildHandler.cpp.

162{
163 LOG_DEBUG("guild", "CMSG_GUILD_SET_OFFICER_NOTE [{}]: Target: {}, Note: {}",
164 GetPlayerInfo(), packet.NoteeName, packet.Note);
165
166 if (normalizePlayerName(packet.NoteeName))
167 if (Guild* guild = GetPlayer()->GetGuild())
168 guild->HandleSetMemberNote(this, packet.NoteeName, packet.Note, false);
169}
String< 31, Strings::NoHyperlinks > Note
Definition: GuildPackets.h:320

◆ HandleGuildSetPublicNoteOpcode()

void WorldSession::HandleGuildSetPublicNoteOpcode ( WorldPackets::Guild::GuildSetMemberNote packet)

Definition at line 152 of file GuildHandler.cpp.

153{
154 LOG_DEBUG("guild", "CMSG_GUILD_SET_PUBLIC_NOTE [{}]: Target: {}, Note: {}", GetPlayerInfo(), packet.NoteeName, packet.Note);
155
156 if (normalizePlayerName(packet.NoteeName))
157 if (Guild* guild = GetPlayer()->GetGuild())
158 guild->HandleSetMemberNote(this, packet.NoteeName, packet.Note, true);
159}

◆ HandleHearthAndResurrect()

void WorldSession::HandleHearthAndResurrect ( WorldPacket recvData)

Definition at line 1688 of file MiscHandler.cpp.

1689{
1690 if (_player->IsInFlight())
1691 return;
1692
1693 if(Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId()))
1694 {
1695 bf->PlayerAskToLeave(_player);
1696 return;
1697 }
1698
1699 AreaTableEntry const* atEntry = sAreaTableStore.LookupEntry(_player->GetAreaId());
1700 if (!atEntry || !(atEntry->flags & AREA_FLAG_WINTERGRASP_2))
1701 return;
1702
1704 _player->ResurrectPlayer(1.0f);
1707}
@ AREA_FLAG_WINTERGRASP_2
Definition: DBCEnums.h:266
uint32 GetAreaId() const
Definition: Object.cpp:3066
float m_homebindZ
Definition: Player.h:2321
uint32 m_homebindMapId
Definition: Player.h:2317
float m_homebindY
Definition: Player.h:2320
float m_homebindO
Definition: Player.h:2322
void BuildPlayerRepop()
Definition: Player.cpp:4310
float m_homebindX
Definition: Player.h:2319

◆ HandleIgnoreTradeOpcode()

void WorldSession::HandleIgnoreTradeOpcode ( WorldPacket recvPacket)

Definition at line 70 of file TradeHandler.cpp.

71{
72 LOG_DEBUG("network", "WORLD: Ignore Trade {}", _player->GetGUID().ToString());
73 // recvPacket.print_storage();
74}

◆ HandleInitiateTradeOpcode()

void WorldSession::HandleInitiateTradeOpcode ( WorldPacket recvPacket)

Definition at line 541 of file TradeHandler.cpp.

542{
543 ObjectGuid ID;
544 recvPacket >> ID;
545
546 if (GetPlayer()->m_trade)
547 return;
548
549 if (!GetPlayer()->IsAlive())
550 {
552 return;
553 }
554
555 if (GetPlayer()->HasUnitState(UNIT_STATE_STUNNED))
556 {
558 return;
559 }
560
561 if (isLogingOut())
562 {
564 return;
565 }
566
567 if (GetPlayer()->IsInFlight())
568 {
570 return;
571 }
572
573 if (GetPlayer()->getLevel() < sWorld->getIntConfig(CONFIG_TRADE_LEVEL_REQ))
574 {
576 return;
577 }
578
579 if (GetPlayer()->IsSpectator())
580 return;
581
583
584 if (!pOther)
585 {
587 return;
588 }
589
590 if (pOther == GetPlayer() || pOther->m_trade)
591 {
593 return;
594 }
595
596 if (!pOther->IsAlive())
597 {
599 return;
600 }
601
602 if (pOther->IsInFlight())
603 {
605 return;
606 }
607
608 if (pOther->HasUnitState(UNIT_STATE_STUNNED))
609 {
611 return;
612 }
613
614 if (pOther->GetSession()->isLogingOut())
615 {
617 return;
618 }
619
620 if (pOther->GetSocial()->HasIgnore(GetPlayer()->GetGUID()))
621 {
623 return;
624 }
625
626 if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_TRADE) && pOther->GetTeamId() != _player->GetTeamId())
627 {
629 return;
630 }
631
632 if (!pOther->IsWithinDistInMap(_player, 10.0f, false))
633 {
635 return;
636 }
637
638 if (pOther->getLevel() < sWorld->getIntConfig(CONFIG_TRADE_LEVEL_REQ))
639 {
641 return;
642 }
643
644 if (!sScriptMgr->CanInitTrade(_player, pOther))
645 return;
646
647 // OK start trade
648 _player->m_trade = new TradeData(_player, pOther);
649 pOther->m_trade = new TradeData(pOther, _player);
650
653 data << _player->GetGUID();
654 pOther->GetSession()->SendPacket(&data);
655}
@ UNIT_STATE_STUNNED
Definition: Unit.h:328
@ LANG_TRADE_OTHER_REQ
Definition: Language.h:1160
@ LANG_TRADE_REQ
Definition: Language.h:1159
@ CONFIG_TRADE_LEVEL_REQ
Definition: IWorld.h:289
@ CONFIG_ALLOW_TWO_SIDE_TRADE
Definition: IWorld.h:86
@ TRADE_STATUS_YOU_STUNNED
@ TRADE_STATUS_IGNORE_YOU
@ TRADE_STATUS_YOU_DEAD
@ TRADE_STATUS_YOU_LOGOUT
@ TRADE_STATUS_TARGET_DEAD
@ TRADE_STATUS_NO_TARGET
@ TRADE_STATUS_BEGIN_TRADE
@ TRADE_STATUS_TARGET_LOGOUT
@ TRADE_STATUS_TARGET_STUNNED
@ TRADE_STATUS_TARGET_TO_FAR
@ TRADE_STATUS_BUSY
@ TRADE_STATUS_WRONG_FACTION
@ SMSG_TRADE_STATUS
Definition: Opcodes.h:318
bool isLogingOut() const
Is the user engaged in a log out process?
Definition: WorldSession.h:382

◆ HandleInspectArenaTeamsOpcode()

void WorldSession::HandleInspectArenaTeamsOpcode ( WorldPacket recvData)

Definition at line 29 of file ArenaTeamHandler.cpp.

30{
31 LOG_DEBUG("network", "MSG_INSPECT_ARENA_TEAMS");
32
33 ObjectGuid guid;
34 recvData >> guid;
35 LOG_DEBUG("network", "Inspect Arena stats ({})", guid.ToString());
36
37 if (Player* player = ObjectAccessor::FindPlayer(guid))
38 {
39 for (uint8 i = 0; i < MAX_ARENA_SLOT; ++i)
40 {
41 if (uint32 a_id = player->GetArenaTeamId(i))
42 {
43 if (ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(a_id))
44 arenaTeam->Inspect(this, player->GetGUID());
45 }
46 }
47 }
48}
#define MAX_ARENA_SLOT
Definition: ArenaTeam.h:135

◆ HandleInspectHonorStatsOpcode()

void WorldSession::HandleInspectHonorStatsOpcode ( WorldPacket recvPacket)

Definition at line 1065 of file MiscHandler.cpp.

1066{
1067 ObjectGuid guid;
1068 recv_data >> guid;
1069
1070 Player* player = ObjectAccessor::GetPlayer(*_player, guid);
1071 if (!player)
1072 {
1073 LOG_DEBUG("network", "MSG_INSPECT_HONOR_STATS: No player found from {}", guid.ToString());
1074 return;
1075 }
1076
1077 WorldPacket data(MSG_INSPECT_HONOR_STATS, 8 + 1 + 4 * 4);
1078 data << player->GetGUID();
1079 data << uint8(player->GetHonorPoints());
1080 data << uint32(player->GetUInt32Value(PLAYER_FIELD_KILLS));
1084 SendPacket(&data);
1085}
@ PLAYER_FIELD_TODAY_CONTRIBUTION
Definition: UpdateFields.h:375
@ PLAYER_FIELD_KILLS
Definition: UpdateFields.h:374
@ PLAYER_FIELD_YESTERDAY_CONTRIBUTION
Definition: UpdateFields.h:376
@ PLAYER_FIELD_LIFETIME_HONORABLE_KILLS
Definition: UpdateFields.h:377
@ MSG_INSPECT_HONOR_STATS
Definition: Opcodes.h:756
uint32 GetHonorPoints() const
Definition: Player.h:2102

◆ HandleInspectOpcode()

void WorldSession::HandleInspectOpcode ( WorldPacket recvPacket)

Definition at line 1031 of file MiscHandler.cpp.

1032{
1033 ObjectGuid guid;
1034 recv_data >> guid;
1035
1036 LOG_DEBUG("network", "WORLD: Received CMSG_INSPECT");
1037
1038 Player* player = ObjectAccessor::GetPlayer(*_player, guid);
1039 if (!player)
1040 {
1041 LOG_DEBUG("network", "CMSG_INSPECT: No player found from {}", guid.ToString());
1042 return;
1043 }
1044
1045 uint32 talent_points = 0x47;
1046 uint32 guid_size = player->GetPackGUID().size();
1047 WorldPacket data(SMSG_INSPECT_TALENT, guid_size + 4 + talent_points);
1048 data << player->GetPackGUID();
1049
1050 if (sWorld->getBoolConfig(CONFIG_TALENTS_INSPECTING) || _player->IsGameMaster())
1051 {
1052 player->BuildPlayerTalentsInfoData(&data);
1053 }
1054 else
1055 {
1056 data << uint32(0); // unspentTalentPoints
1057 data << uint8(0); // talentGroupCount
1058 data << uint8(0); // talentGroupIndex
1059 }
1060
1061 player->BuildEnchantmentsInfoData(&data);
1062 SendPacket(&data);
1063}
@ CONFIG_TALENTS_INSPECTING
Definition: IWorld.h:104
@ SMSG_INSPECT_TALENT
Definition: Opcodes.h:1042
std::size_t size() const
Definition: ObjectGuid.h:276
void BuildEnchantmentsInfoData(WorldPacket *data)
Definition: Player.cpp:14124
void BuildPlayerTalentsInfoData(WorldPacket *data)
Definition: Player.cpp:14007

◆ HandleInstanceLockResponse()

void WorldSession::HandleInstanceLockResponse ( WorldPacket recvPacket)

Definition at line 1709 of file MiscHandler.cpp.

1710{
1711 uint8 accept;
1712 recvPacket >> accept;
1713
1715 {
1716 LOG_DEBUG("network.opcode", "InstanceLockResponse: Player {} ({}) tried to bind himself/teleport to graveyard without a pending bind!",
1718 return;
1719 }
1720
1721 if (accept)
1723 else
1725
1726 _player->SetPendingBind(0, 0);
1727}
uint32 GetPendingBind() const
Definition: Player.h:2389
bool HasPendingBind() const
Definition: Player.h:2388
void RepopAtGraveyard()
Definition: Player.cpp:4805
void SetPendingBind(uint32 instanceId, uint32 bindTimer)
Definition: Player.h:2387
void BindToInstance()

◆ HandleItemNameQueryOpcode()

void WorldSession::HandleItemNameQueryOpcode ( WorldPacket recvPacket)

Definition at line 1200 of file ItemHandler.cpp.

1201{
1202 uint32 itemid;
1203 recvData >> itemid;
1204 recvData.read_skip<uint64>(); // guid
1205
1206 LOG_DEBUG("network", "WORLD: CMSG_ITEM_NAME_QUERY {}", itemid);
1207 ItemSetNameEntry const* pName = sObjectMgr->GetItemSetNameEntry(itemid);
1208 if (pName)
1209 {
1210 std::string Name = pName->name;
1212 if (loc_idx >= 0)
1213 if (ItemSetNameLocale const* isnl = sObjectMgr->GetItemSetNameLocale(itemid))
1214 ObjectMgr::GetLocaleString(isnl->Name, loc_idx, Name);
1215
1216 WorldPacket data(SMSG_ITEM_NAME_QUERY_RESPONSE, (4 + Name.size() + 1 + 4));
1217 data << uint32(itemid);
1218 data << Name;
1219 data << uint32(pName->InventoryType);
1220 SendPacket(&data);
1221 }
1222}
@ SMSG_ITEM_NAME_QUERY_RESPONSE
Definition: Opcodes.h:739
std::string name
Definition: ItemTemplate.h:848

◆ HandleItemQuerySingleOpcode()

void WorldSession::HandleItemQuerySingleOpcode ( WorldPacket recvPacket)

Definition at line 536 of file ItemHandler.cpp.

537{
538 //LOG_DEBUG("network.opcode", "WORLD: CMSG_ITEM_QUERY_SINGLE");
539 uint32 item;
540 recvData >> item;
541
542 LOG_DEBUG("network.opcode", "STORAGE: Item Query = {}", item);
543
544 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item);
545 if (pProto)
546 {
547 std::string Name = pProto->Name1;
548 std::string Description = pProto->Description;
549
550 int loc_idx = GetSessionDbLocaleIndex();
551 if (loc_idx >= 0)
552 {
553 if (ItemLocale const* il = sObjectMgr->GetItemLocale(pProto->ItemId))
554 {
555 ObjectMgr::GetLocaleString(il->Name, loc_idx, Name);
556 ObjectMgr::GetLocaleString(il->Description, loc_idx, Description);
557 }
558 }
559 // guess size
561 queryData << pProto->ItemId;
562 queryData << pProto->Class;
563 queryData << pProto->SubClass;
564 queryData << pProto->SoundOverrideSubclass;
565 queryData << Name;
566 queryData << uint8(0x00); //pProto->Name2; // blizz not send name there, just uint8(0x00); <-- \0 = empty string = empty name...
567 queryData << uint8(0x00); //pProto->Name3; // blizz not send name there, just uint8(0x00);
568 queryData << uint8(0x00); //pProto->Name4; // blizz not send name there, just uint8(0x00);
569 queryData << pProto->DisplayInfoID;
570 queryData << pProto->Quality;
571 queryData << pProto->Flags;
572 queryData << pProto->Flags2;
573 queryData << pProto->BuyPrice;
574 queryData << pProto->SellPrice;
575 queryData << pProto->InventoryType;
576 queryData << pProto->AllowableClass;
577 queryData << pProto->AllowableRace;
578 queryData << pProto->ItemLevel;
579 queryData << pProto->RequiredLevel;
580 queryData << pProto->RequiredSkill;
581 queryData << pProto->RequiredSkillRank;
582 queryData << pProto->RequiredSpell;
583 queryData << pProto->RequiredHonorRank;
584 queryData << pProto->RequiredCityRank;
585 queryData << pProto->RequiredReputationFaction;
586 queryData << pProto->RequiredReputationRank;
587 queryData << int32(pProto->MaxCount);
588 queryData << int32(pProto->Stackable);
589 queryData << pProto->ContainerSlots;
590 queryData << pProto->StatsCount; // item stats count
591 for (uint32 i = 0; i < pProto->StatsCount; ++i)
592 {
593 queryData << pProto->ItemStat[i].ItemStatType;
594 queryData << pProto->ItemStat[i].ItemStatValue;
595 }
596 queryData << pProto->ScalingStatDistribution; // scaling stats distribution
597 queryData << pProto->ScalingStatValue; // some kind of flags used to determine stat values column
598 for (int i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
599 {
600 queryData << pProto->Damage[i].DamageMin;
601 queryData << pProto->Damage[i].DamageMax;
602 queryData << pProto->Damage[i].DamageType;
603 }
604
605 // resistances (7)
606 queryData << pProto->Armor;
607 queryData << pProto->HolyRes;
608 queryData << pProto->FireRes;
609 queryData << pProto->NatureRes;
610 queryData << pProto->FrostRes;
611 queryData << pProto->ShadowRes;
612 queryData << pProto->ArcaneRes;
613
614 queryData << pProto->Delay;
615 queryData << pProto->AmmoType;
616 queryData << pProto->RangedModRange;
617
618 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
619 {
620 // send DBC data for cooldowns in same way as it used in Spell::SendSpellCooldown
621 // use `item_template` or if not set then only use spell cooldowns
622 SpellInfo const* spell = sSpellMgr->GetSpellInfo(pProto->Spells[s].SpellId);
623 if (spell)
624 {
625 bool db_data = pProto->Spells[s].SpellCooldown >= 0 || pProto->Spells[s].SpellCategoryCooldown >= 0;
626
627 queryData << pProto->Spells[s].SpellId;
628 queryData << pProto->Spells[s].SpellTrigger;
629 queryData << int32(pProto->Spells[s].SpellCharges);
630
631 if (db_data)
632 {
633 queryData << uint32(pProto->Spells[s].SpellCooldown);
634 queryData << uint32(pProto->Spells[s].SpellCategory);
635 queryData << uint32(pProto->Spells[s].SpellCategoryCooldown);
636 }
637 else
638 {
639 queryData << uint32(spell->RecoveryTime);
640 queryData << uint32(spell->GetCategory());
641 queryData << uint32(spell->CategoryRecoveryTime);
642 }
643 }
644 else
645 {
646 queryData << uint32(0);
647 queryData << uint32(0);
648 queryData << uint32(0);
649 queryData << uint32(-1);
650 queryData << uint32(0);
651 queryData << uint32(-1);
652 }
653 }
654 queryData << pProto->Bonding;
655 queryData << Description;
656 queryData << pProto->PageText;
657 queryData << pProto->LanguageID;
658 queryData << pProto->PageMaterial;
659 queryData << pProto->StartQuest;
660 queryData << pProto->LockID;
661 queryData << int32(pProto->Material);
662 queryData << pProto->Sheath;
663 queryData << pProto->RandomProperty;
664 queryData << pProto->RandomSuffix;
665 queryData << pProto->Block;
666 queryData << pProto->ItemSet;
667 queryData << pProto->MaxDurability;
668 queryData << pProto->Area;
669 queryData << pProto->Map; // Added in 1.12.x & 2.0.1 client branch
670 queryData << pProto->BagFamily;
671 queryData << pProto->TotemCategory;
672 for (int s = 0; s < MAX_ITEM_PROTO_SOCKETS; ++s)
673 {
674 queryData << pProto->Socket[s].Color;
675 queryData << pProto->Socket[s].Content;
676 }
677 queryData << pProto->socketBonus;
678 queryData << pProto->GemProperties;
679 queryData << pProto->RequiredDisenchantSkill;
680 queryData << pProto->ArmorDamageModifier;
681 queryData << pProto->Duration; // added in 2.4.2.8209, duration (seconds)
682 queryData << pProto->ItemLimitCategory; // WotLK, ItemLimitCategory
683 queryData << pProto->HolidayId; // Holiday.dbc?
684 SendPacket(&queryData);
685 }
686 else
687 {
688 LOG_DEBUG("network", "WORLD: CMSG_ITEM_QUERY_SINGLE - NO item INFO! (ENTRY: {})", item);
690 queryData << uint32(item | 0x80000000);
691 SendPacket(&queryData);
692 }
693}
#define MAX_ITEM_PROTO_SOCKETS
Definition: ItemTemplate.h:623
#define MAX_ITEM_PROTO_DAMAGES
Definition: ItemTemplate.h:622
#define MAX_ITEM_PROTO_SPELLS
Definition: ItemTemplate.h:624
@ SMSG_ITEM_QUERY_SINGLE_RESPONSE
Definition: Opcodes.h:118
float DamageMin
Definition: ItemTemplate.h:588
uint32 DamageType
Definition: ItemTemplate.h:590
float DamageMax
Definition: ItemTemplate.h:589
int32 ItemStatValue
Definition: ItemTemplate.h:596
uint32 ItemStatType
Definition: ItemTemplate.h:595
int32 SpellCharges
Definition: ItemTemplate.h:602
uint32 SpellTrigger
Definition: ItemTemplate.h:601
int32 SpellCategoryCooldown
Definition: ItemTemplate.h:606
int32 SpellCooldown
Definition: ItemTemplate.h:604
uint32 SpellCategory
Definition: ItemTemplate.h:605
int32 SpellId
Definition: ItemTemplate.h:600
uint32 Content
Definition: ItemTemplate.h:612
uint32 Color
Definition: ItemTemplate.h:611
int32 RandomProperty
Definition: ItemTemplate.h:681
uint32 Quality
Definition: ItemTemplate.h:635
uint32 ItemLevel
Definition: ItemTemplate.h:644
uint32 RequiredCityRank
Definition: ItemTemplate.h:650
uint32 RequiredSkill
Definition: ItemTemplate.h:646
uint32 RequiredSpell
Definition: ItemTemplate.h:648
uint32 ScalingStatValue
Definition: ItemTemplate.h:659
std::string Description
Definition: ItemTemplate.h:673
uint32 AllowableClass
Definition: ItemTemplate.h:642
uint32 RequiredSkillRank
Definition: ItemTemplate.h:647
_Damage Damage[MAX_ITEM_PROTO_DAMAGES]
Definition: ItemTemplate.h:660
uint32 RequiredHonorRank
Definition: ItemTemplate.h:649
float RangedModRange
Definition: ItemTemplate.h:670
float ArmorDamageModifier
Definition: ItemTemplate.h:694
_Spell Spells[MAX_ITEM_PROTO_SPELLS]
Definition: ItemTemplate.h:671
uint32 socketBonus
Definition: ItemTemplate.h:691
uint32 RequiredDisenchantSkill
Definition: ItemTemplate.h:693
uint32 TotemCategory
Definition: ItemTemplate.h:689
uint32 PageMaterial
Definition: ItemTemplate.h:676
uint32 RequiredLevel
Definition: ItemTemplate.h:645
uint32 ItemSet
Definition: ItemTemplate.h:684
uint32 HolidayId
Definition: ItemTemplate.h:697
uint32 GemProperties
Definition: ItemTemplate.h:692
uint32 RequiredReputationRank
Definition: ItemTemplate.h:652
uint32 ContainerSlots
Definition: ItemTemplate.h:655
uint32 DisplayInfoID
Definition: ItemTemplate.h:634
uint32 AllowableRace
Definition: ItemTemplate.h:643
uint32 RequiredReputationFaction
Definition: ItemTemplate.h:651
uint32 ItemLimitCategory
Definition: ItemTemplate.h:696
uint32 PageText
Definition: ItemTemplate.h:674
uint32 ScalingStatDistribution
Definition: ItemTemplate.h:658
_ItemStat ItemStat[MAX_ITEM_PROTO_STATS]
Definition: ItemTemplate.h:657
uint32 MaxDurability
Definition: ItemTemplate.h:685
uint32 BagFamily
Definition: ItemTemplate.h:688
uint32 InventoryType
Definition: ItemTemplate.h:641
uint32 LanguageID
Definition: ItemTemplate.h:675
uint32 AmmoType
Definition: ItemTemplate.h:669
int32 RandomSuffix
Definition: ItemTemplate.h:682
uint32 Duration
Definition: ItemTemplate.h:695
uint32 SubClass
Definition: ItemTemplate.h:631
uint32 StartQuest
Definition: ItemTemplate.h:677
int32 SoundOverrideSubclass
Definition: ItemTemplate.h:632
_Socket Socket[MAX_ITEM_PROTO_SOCKETS]
Definition: ItemTemplate.h:690
uint32 StatsCount
Definition: ItemTemplate.h:656
uint32 Bonding
Definition: ItemTemplate.h:672
uint32 SellPrice
Definition: ItemTemplate.h:640
uint32 GetCategory() const
Definition: SpellInfo.cpp:863
uint32 RecoveryTime
Definition: SpellInfo.h:346
uint32 CategoryRecoveryTime
Definition: SpellInfo.h:347

◆ HandleItemRefund()

void WorldSession::HandleItemRefund ( WorldPacket recvData)

Definition at line 1590 of file ItemHandler.cpp.

1591{
1592 LOG_DEBUG("network", "WORLD: CMSG_ITEM_REFUND");
1593 ObjectGuid guid;
1594 recvData >> guid; // item guid
1595
1596 Item* item = _player->GetItemByGuid(guid);
1597 if (!item)
1598 {
1599 LOG_DEBUG("network", "Item refund: item not found!");
1600 return;
1601 }
1602
1603 // Don't try to refund item currently being disenchanted
1604 if (_player->GetLootGUID() == guid)
1605 return;
1606
1607 GetPlayer()->RefundItem(item);
1608}
void RefundItem(Item *item)
Definition: Player.cpp:15280

◆ HandleItemRefundInfoRequest()

void WorldSession::HandleItemRefundInfoRequest ( WorldPacket recvData)

Definition at line 1573 of file ItemHandler.cpp.

1574{
1575 LOG_DEBUG("network", "WORLD: CMSG_ITEM_REFUND_INFO");
1576
1577 ObjectGuid guid;
1578 recvData >> guid; // item guid
1579
1580 Item* item = _player->GetItemByGuid(guid);
1581 if (!item)
1582 {
1583 LOG_DEBUG("network", "Item refund: item not found!");
1584 return;
1585 }
1586
1587 GetPlayer()->SendRefundInfo(item);
1588}
void SendRefundInfo(Item *item)
Definition: Player.cpp:15209

◆ HandleItemTextQuery()

void WorldSession::HandleItemTextQuery ( WorldPacket recvData)

Handles the packet sent by the client when requesting information about item text.

This function is called when player clicks on item which has some flag set

Definition at line 1615 of file ItemHandler.cpp.

1616{
1617 ObjectGuid itemGuid;
1618 recvData >> itemGuid;
1619
1620 LOG_DEBUG("network", "CMSG_ITEM_TEXT_QUERY item: {}", itemGuid.ToString());
1621
1622 WorldPacket data(SMSG_ITEM_TEXT_QUERY_RESPONSE, 50); // guess size
1623
1624 if (Item* item = _player->GetItemByGuid(itemGuid))
1625 {
1626 data << uint8(0); // has text
1627 data << itemGuid; // item guid
1628 data << item->GetText();
1629 }
1630 else
1631 {
1632 data << uint8(1); // no text
1633 }
1634
1635 SendPacket(&data);
1636}
@ SMSG_ITEM_TEXT_QUERY_RESPONSE
Definition: Opcodes.h:610

◆ HandleJoinChannel()

void WorldSession::HandleJoinChannel ( WorldPacket recvPacket)

Definition at line 23 of file ChannelHandler.cpp.

24{
25 uint32 channelId;
26 uint8 unknown1, unknown2;
27 std::string channelName, password;
28
29 recvPacket >> channelId >> unknown1 >> unknown2 >> channelName >> password;
30
31 LOG_DEBUG("chat.system", "CMSG_JOIN_CHANNEL {} Channel: {}, unk1: {}, unk2: {}, channel: {}, password: {}", GetPlayerInfo(), channelId, unknown1, unknown2, channelName, password);
32 if (channelId)
33 {
34 ChatChannelsEntry const* channel = sChatChannelsStore.LookupEntry(channelId);
35 if (!channel)
36 return;
37
38 AreaTableEntry const* zone = sAreaTableStore.LookupEntry(GetPlayer()->GetZoneId());
39 if (!zone || !GetPlayer()->CanJoinConstantChannelInZone(channel, zone))
40 return;
41 }
42
43 if (channelName.empty())
44 return;
45
46 if (isdigit(channelName[0]))
47 return;
48
49 if (channelName.size() >= 100 || !DisallowHyperlinksAndMaybeKick(channelName))
50 {
51 return;
52 }
53
55 {
56 if (Channel* channel = cMgr->GetJoinChannel(channelName, channelId))
57 channel->JoinChannel(GetPlayer(), password);
58 }
59}
DBCStorage< ChatChannelsEntry > sChatChannelsStore(ChatChannelsEntryfmt)
bool DisallowHyperlinksAndMaybeKick(std::string_view str)

◆ HandleLearnPreviewTalents()

void WorldSession::HandleLearnPreviewTalents ( WorldPacket recvPacket)

Definition at line 35 of file SkillHandler.cpp.

36{
37 LOG_DEBUG("network", "CMSG_LEARN_PREVIEW_TALENTS");
38
39 uint32 talentsCount;
40 recvPacket >> talentsCount;
41
42 uint32 talentId, talentRank;
43
44 // Client has max 44 talents for tree for 3 trees, rounded up : 150
45 uint32 const MaxTalentsCount = 150;
46
47 for (uint32 i = 0; i < talentsCount && i < MaxTalentsCount; ++i)
48 {
49 recvPacket >> talentId >> talentRank;
50
51 _player->LearnTalent(talentId, talentRank);
52 }
53
55
56 recvPacket.rfinish();
57}
void SendTalentsInfoData(bool pet)
Definition: Player.cpp:14113
void LearnTalent(uint32 talentId, uint32 talentRank, bool command=false)
Definition: Player.cpp:13631

◆ HandleLearnPreviewTalentsPet()

void WorldSession::HandleLearnPreviewTalentsPet ( WorldPacket recvPacket)

Definition at line 1130 of file PetHandler.cpp.

1131{
1132 LOG_DEBUG("network", "CMSG_LEARN_PREVIEW_TALENTS_PET");
1133
1134 ObjectGuid guid;
1135 recvData >> guid;
1136
1137 uint32 talentsCount;
1138 recvData >> talentsCount;
1139
1140 uint32 talentId, talentRank;
1141
1142 // Client has max 24 talents, rounded up : 30
1143 uint32 const MaxTalentsCount = 30;
1144
1145 for (uint32 i = 0; i < talentsCount && i < MaxTalentsCount; ++i)
1146 {
1147 recvData >> talentId >> talentRank;
1148
1149 _player->LearnPetTalent(guid, talentId, talentRank);
1150 }
1151
1153
1154 recvData.rfinish();
1155}
void LearnPetTalent(ObjectGuid petGuid, uint32 talentId, uint32 talentRank)
Definition: Player.cpp:13767

◆ HandleLearnTalentOpcode()

void WorldSession::HandleLearnTalentOpcode ( WorldPacket recvPacket)

Definition at line 26 of file SkillHandler.cpp.

27{
28 uint32 talent_id, requested_rank;
29 recvData >> talent_id >> requested_rank;
30
31 _player->LearnTalent(talent_id, requested_rank);
33}

◆ HandleLeaveChannel()

void WorldSession::HandleLeaveChannel ( WorldPacket recvPacket)

Definition at line 61 of file ChannelHandler.cpp.

62{
63 uint32 unk;
64 std::string channelName;
65 recvPacket >> unk >> channelName;
66
67 LOG_DEBUG("chat.system", "CMSG_LEAVE_CHANNEL {} Channel: {}, unk1: {}",
68 GetPlayerInfo(), channelName, unk);
69 if (channelName.empty())
70 return;
71
73 {
74 if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
75 channel->LeaveChannel(GetPlayer(), true);
76 }
77}

◆ HandleLfgGetStatus()

void WorldSession::HandleLfgGetStatus ( WorldPacket recvData)

Definition at line 272 of file LFGHandler.cpp.

273{
274 LOG_DEBUG("lfg", "CMSG_LFG_GET_STATUS {}", GetPlayerInfo());
275
276 ObjectGuid guid = GetPlayer()->GetGUID();
277 lfg::LfgUpdateData updateData = sLFGMgr->GetLfgStatus(guid);
278
279 if (GetPlayer()->GetGroup())
280 {
281 SendLfgUpdateParty(updateData);
282 updateData.dungeons.clear();
283 SendLfgUpdatePlayer(updateData);
284 }
285 else
286 {
287 SendLfgUpdatePlayer(updateData);
288 updateData.dungeons.clear();
289 SendLfgUpdateParty(updateData);
290 }
291}
LfgDungeonSet dungeons
Definition: LFGMgr.h:299
void SendLfgUpdatePlayer(lfg::LfgUpdateData const &updateData)
Definition: LFGHandler.cpp:293
void SendLfgUpdateParty(lfg::LfgUpdateData const &updateData)
Definition: LFGHandler.cpp:330

◆ HandleLfgJoinOpcode()

void WorldSession::HandleLfgJoinOpcode ( WorldPackets::LFG::LFGJoin lfgJoin)

Definition at line 49 of file LFGHandler.cpp.

50{
52 (GetPlayer()->GetGroup() && GetPlayer()->GetGroup()->GetLeaderGUID() != GetPlayer()->GetGUID() &&
53 (GetPlayer()->GetGroup()->GetMembersCount() == MAXGROUPSIZE || !GetPlayer()->GetGroup()->isLFGGroup())))
54 return;
55
56 if (packet.Slots.empty())
57 {
58 LOG_DEBUG("lfg", "CMSG_LFG_JOIN {} no dungeons selected", GetPlayerInfo().c_str());
59 return;
60 }
61
62 lfg::LfgDungeonSet newDungeons;
63 for (uint32 slot : packet.Slots)
64 {
65 uint32 dungeon = slot & 0x00FFFFFF; // remove the type from the dungeon entry
66 if (sLFGDungeonStore.LookupEntry(dungeon))
67 newDungeons.insert(dungeon);
68 }
69
70 LOG_DEBUG("network", "CMSG_LFG_JOIN [{}] roles: {}, Dungeons: {}, Comment: {}",
71 GetPlayerInfo().c_str(), packet.Roles, newDungeons.size(), packet.Comment.c_str());
72
73 sLFGMgr->JoinLfg(GetPlayer(), uint8(packet.Roles), newDungeons, packet.Comment);
74}
DBCStorage< LFGDungeonEntry > sLFGDungeonStore(LFGDungeonEntryfmt)
#define MAXGROUPSIZE
Definition: Group.h:42
@ LFG_OPTION_ENABLE_SEASONAL_BOSSES
Definition: LFGMgr.h:43
@ LFG_OPTION_ENABLE_DUNGEON_FINDER
Definition: LFGMgr.h:41
@ LFG_OPTION_ENABLE_RAID_BROWSER
Definition: LFGMgr.h:42
std::set< uint32 > LfgDungeonSet
Definition: LFG.h:109

◆ HandleLfgLeaveOpcode()

void WorldSession::HandleLfgLeaveOpcode ( WorldPackets::LFG::LFGLeave lfgleave)

Definition at line 76 of file LFGHandler.cpp.

77{
78 Group* group = GetPlayer()->GetGroup();
79 ObjectGuid guid = GetPlayer()->GetGUID();
80 ObjectGuid gguid = group ? group->GetGUID() : guid;
81
82 LOG_DEBUG("network", "CMSG_LFG_LEAVE [{}] in group: {}", guid.ToString(), group ? 1 : 0);
83
84 // Check cheating - only leader can leave the queue
85 if (!group || group->GetLeaderGUID() == guid)
86 {
87 sLFGMgr->LeaveLfg(sLFGMgr->GetState(guid) == lfg::LFG_STATE_RAIDBROWSER ? guid : gguid);
88 sLFGMgr->LeaveAllLfgQueues(guid, true, group ? group->GetGUID() : ObjectGuid::Empty);
89 }
90}
@ LFG_STATE_RAIDBROWSER
Definition: LFG.h:78
ObjectGuid GetGUID() const
Definition: Group.cpp:2241

◆ HandleLfgPartyLockInfoRequestOpcode()

void WorldSession::HandleLfgPartyLockInfoRequestOpcode ( WorldPacket recvData)

Definition at line 221 of file LFGHandler.cpp.

222{
223 ObjectGuid guid = GetPlayer()->GetGUID();
224 LOG_DEBUG("network", "CMSG_LFG_PARTY_LOCK_INFO_REQUEST [{}]", guid.ToString());
225
226 Group* group = GetPlayer()->GetGroup();
227 if (!group)
228 return;
229
230 // Get the locked dungeons of the other party members
231 lfg::LfgLockPartyMap lockMap;
232 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
233 {
234 Player* plrg = itr->GetSource();
235 if (!plrg)
236 continue;
237
238 ObjectGuid pguid = plrg->GetGUID();
239 if (pguid == guid)
240 continue;
241
242 sLFGMgr->InitializeLockedDungeons(plrg); // pussywizard
243 lockMap[pguid] = sLFGMgr->GetLockedDungeons(pguid);
244 }
245
246 uint32 size = 0;
247 for (lfg::LfgLockPartyMap::const_iterator it = lockMap.begin(); it != lockMap.end(); ++it)
248 size += 8 + 4 + uint32(it->second.size()) * (4 + 4);
249
250 LOG_DEBUG("network", "SMSG_LFG_PARTY_INFO [{}]", guid.ToString());
251 WorldPacket data(SMSG_LFG_PARTY_INFO, 1 + size);
252 BuildPartyLockDungeonBlock(data, lockMap);
253 SendPacket(&data);
254}
void BuildPartyLockDungeonBlock(WorldPacket &data, const lfg::LfgLockPartyMap &lockMap)
Definition: LFGHandler.cpp:39
@ SMSG_LFG_PARTY_INFO
Definition: Opcodes.h:912
std::map< ObjectGuid, LfgLockMap > LfgLockPartyMap
Definition: LFG.h:111

◆ HandleLfgPlayerLockInfoRequestOpcode()

void WorldSession::HandleLfgPlayerLockInfoRequestOpcode ( WorldPacket recvData)

Definition at line 149 of file LFGHandler.cpp.

150{
151 ObjectGuid guid = GetPlayer()->GetGUID();
152 LOG_DEBUG("network", "CMSG_LFG_PLAYER_LOCK_INFO_REQUEST [{}]", guid.ToString());
153
154 // Get Random dungeons that can be done at a certain level and expansion
155 uint8 level = GetPlayer()->getLevel();
156 lfg::LfgDungeonSet const& randomDungeons =
157 sLFGMgr->GetRandomAndSeasonalDungeons(level, GetPlayer()->GetSession()->Expansion());
158
159 // Get player locked Dungeons
160 sLFGMgr->InitializeLockedDungeons(GetPlayer()); // pussywizard
161 lfg::LfgLockMap const& lock = sLFGMgr->GetLockedDungeons(guid);
162 uint32 rsize = uint32(randomDungeons.size());
163 uint32 lsize = uint32(lock.size());
164
165 LOG_DEBUG("network", "SMSG_LFG_PLAYER_INFO [{}]", guid.ToString());
166 WorldPacket data(SMSG_LFG_PLAYER_INFO, 1 + rsize * (4 + 1 + 4 + 4 + 4 + 4 + 1 + 4 + 4 + 4) + 4 + lsize * (1 + 4 + 4 + 4 + 4 + 1 + 4 + 4 + 4));
167
168 data << uint8(randomDungeons.size()); // Random Dungeon count
169 for (lfg::LfgDungeonSet::const_iterator it = randomDungeons.begin(); it != randomDungeons.end(); ++it)
170 {
171 data << uint32(*it); // Dungeon Entry (id + type)
172 lfg::LfgReward const* reward = sLFGMgr->GetRandomDungeonReward(*it, level);
173 Quest const* quest = nullptr;
174 bool done = false;
175 if (reward)
176 {
177 quest = sObjectMgr->GetQuestTemplate(reward->firstQuest);
178 if (quest)
179 {
180 done = !GetPlayer()->CanRewardQuest(quest, false);
181 if (done)
182 quest = sObjectMgr->GetQuestTemplate(reward->otherQuest);
183 }
184 }
185
186 if (quest)
187 {
188 uint8 playerLevel = GetPlayer() ? GetPlayer()->getLevel() : 0;
189 data << uint8(done);
190 data << uint32(quest->GetRewOrReqMoney(playerLevel));
191 data << uint32(quest->XPValue(playerLevel));
192 data << uint32(0);
193 data << uint32(0);
194 data << uint8(quest->GetRewItemsCount());
195 if (quest->GetRewItemsCount())
196 {
197 for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i)
198 if (uint32 itemId = quest->RewardItemId[i])
199 {
200 ItemTemplate const* item = sObjectMgr->GetItemTemplate(itemId);
201 data << uint32(itemId);
202 data << uint32(item ? item->DisplayInfoID : 0);
203 data << uint32(quest->RewardItemIdCount[i]);
204 }
205 }
206 }
207 else
208 {
209 data << uint8(0);
210 data << uint32(0);
211 data << uint32(0);
212 data << uint32(0);
213 data << uint32(0);
214 data << uint8(0);
215 }
216 }
217 BuildPlayerLockDungeonBlock(data, lock);
218 SendPacket(&data);
219}
void BuildPlayerLockDungeonBlock(WorldPacket &data, lfg::LfgLockMap const &lock)
Definition: LFGHandler.cpp:29
#define QUEST_REWARDS_COUNT
Definition: QuestDef.h:39
@ SMSG_LFG_PLAYER_INFO
Definition: Opcodes.h:909
std::map< uint32, uint32 > LfgLockMap
Definition: LFG.h:110
uint32 firstQuest
Definition: LFGMgr.h:340
uint32 otherQuest
Definition: LFGMgr.h:341
bool CanRewardQuest(Quest const *quest, bool msg)
uint32 RewardItemIdCount[QUEST_REWARDS_COUNT]
Definition: QuestDef.h:306
uint32 GetRewItemsCount() const
Definition: QuestDef.h:318
uint32 XPValue(uint8 playerLevel=0) const
Definition: QuestDef.cpp:199
int32 GetRewOrReqMoney(uint8 playerLevel=0) const
Definition: QuestDef.cpp:239
uint32 RewardItemId[QUEST_REWARDS_COUNT]
Definition: QuestDef.h:305

◆ HandleLfgProposalResultOpcode()

void WorldSession::HandleLfgProposalResultOpcode ( WorldPacket recvData)

Definition at line 92 of file LFGHandler.cpp.

93{
94 uint32 proposalID; // Internal lfgGroupID
95 bool accept; // Accept to join?
96 recvData >> proposalID;
97 recvData >> accept;
98
99 LOG_DEBUG("network", "CMSG_LFG_PROPOSAL_RESULT [{}] proposal: {} accept: {}", GetPlayer()->GetGUID().ToString(), proposalID, accept ? 1 : 0);
100 sLFGMgr->UpdateProposal(proposalID, GetPlayer()->GetGUID(), accept);
101}

◆ HandleLfgSetBootVoteOpcode()

void WorldSession::HandleLfgSetBootVoteOpcode ( WorldPacket recvData)

Definition at line 130 of file LFGHandler.cpp.

131{
132 bool agree; // Agree to kick player
133 recvData >> agree;
134
135 ObjectGuid guid = GetPlayer()->GetGUID();
136 LOG_DEBUG("network", "CMSG_LFG_SET_BOOT_VOTE [{}] agree: {}", guid.ToString(), agree ? 1 : 0);
137 sLFGMgr->UpdateBoot(guid, agree);
138}

◆ HandleLfgSetCommentOpcode()

void WorldSession::HandleLfgSetCommentOpcode ( WorldPacket recvData)

Definition at line 119 of file LFGHandler.cpp.

120{
121 std::string comment;
122 recvData >> comment;
123 ObjectGuid guid = GetPlayer()->GetGUID();
124 LOG_DEBUG("network", "CMSG_LFG_SET_COMMENT [{}] comment: {}", guid.ToString(), comment);
125
126 sLFGMgr->SetComment(GetPlayer()->GetGUID(), comment);
127 sLFGMgr->LfrSetComment(GetPlayer(), comment);
128}

◆ HandleLfgSetRolesOpcode()

void WorldSession::HandleLfgSetRolesOpcode ( WorldPacket recvData)

Definition at line 103 of file LFGHandler.cpp.

104{
105 uint8 roles;
106 recvData >> roles; // Player Group Roles
107 ObjectGuid guid = GetPlayer()->GetGUID();
108 Group* group = GetPlayer()->GetGroup();
109 if (!group)
110 {
111 LOG_DEBUG("network", "CMSG_LFG_SET_ROLES [{}] Not in group", guid.ToString());
112 return;
113 }
114 ObjectGuid gguid = group->GetGUID();
115 LOG_DEBUG("network", "CMSG_LFG_SET_ROLES: Group [{}], Player [{}], Roles: {}", gguid.ToString(), guid.ToString(), roles);
116 sLFGMgr->UpdateRoleCheck(gguid, guid, roles);
117}

◆ HandleLfgTeleportOpcode()

void WorldSession::HandleLfgTeleportOpcode ( WorldPacket recvData)

Definition at line 140 of file LFGHandler.cpp.

141{
142 bool out;
143 recvData >> out;
144
145 LOG_DEBUG("network", "CMSG_LFG_TELEPORT [{}] out: {}", GetPlayer()->GetGUID().ToString(), out ? 1 : 0);
146 sLFGMgr->TeleportPlayer(GetPlayer(), out);
147}

◆ HandleLfrSearchJoinOpcode()

void WorldSession::HandleLfrSearchJoinOpcode ( WorldPacket recvData)

Definition at line 256 of file LFGHandler.cpp.

257{
258 uint32 dungeonId;
259 recvData >> dungeonId;
260 dungeonId = (dungeonId & 0x00FFFFFF); // remove the type from the dungeon entry
261 sLFGMgr->LfrSearchAdd(GetPlayer(), dungeonId);
262 sLFGMgr->SendRaidBrowserCachedList(GetPlayer(), dungeonId);
263}

◆ HandleLfrSearchLeaveOpcode()

void WorldSession::HandleLfrSearchLeaveOpcode ( WorldPacket recvData)

Definition at line 265 of file LFGHandler.cpp.

266{
267 uint32 dungeonId;
268 recvData >> dungeonId;
269 sLFGMgr->LfrSearchRemove(GetPlayer());
270}

◆ HandleListInventoryOpcode()

void WorldSession::HandleListInventoryOpcode ( WorldPacket recvPacket)

Definition at line 978 of file ItemHandler.cpp.

979{
980 ObjectGuid guid;
981
982 recvData >> guid;
983
984 if (!GetPlayer()->IsAlive())
985 return;
986
987 LOG_DEBUG("network", "WORLD: Recvd CMSG_LIST_INVENTORY");
988
989 SendListInventory(guid);
990}
void SendListInventory(ObjectGuid guid, uint32 vendorEntry=0)

◆ HandleListStabledPetsOpcode()

void WorldSession::HandleListStabledPetsOpcode ( WorldPacket recvPacket)

Definition at line 466 of file NPCHandler.cpp.

467{
468 LOG_DEBUG("network", "WORLD: Recv MSG_LIST_STABLED_PETS");
469 ObjectGuid npcGUID;
470
471 recvData >> npcGUID;
472
473 if (!CheckStableMaster(npcGUID))
474 return;
475
476 // remove fake death
477 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
479
480 // remove mounts this fix bug where getting pet from stable while mounted deletes pet.
481 if (GetPlayer()->IsMounted())
483
484 SendStablePet(npcGUID);
485}
void SendStablePet(ObjectGuid guid)
Definition: NPCHandler.cpp:487

◆ HandleLoadActionsSwitchSpec()

void WorldSession::HandleLoadActionsSwitchSpec ( PreparedQueryResult  result)

Definition at line 587 of file MiscHandler.cpp.

588{
589 if (!GetPlayer())
590 return;
591
592 if (result)
593 GetPlayer()->_LoadActions(result);
594
596}
void _LoadActions(PreparedQueryResult result)
void SendActionButtons(uint32 state) const
Definition: Player.cpp:5439

◆ HandleLogoutCancelOpcode()

void WorldSession::HandleLogoutCancelOpcode ( WorldPackets::Character::LogoutCancel logoutCancel)

Definition at line 482 of file MiscHandler.cpp.

483{
485
487
488 // not remove flags if can't free move - its not set in Logout request code.
489 if (GetPlayer()->CanFreeMove())
490 {
491 GetPlayer()->SetRooted(false);
492
495 }
496}
@ UNIT_STAND_STATE_STAND
Definition: Unit.h:53
@ UNIT_FLAG_STUNNED
Definition: Unit.h:466
void SetRooted(bool apply, bool isStun=false)
Definition: Unit.cpp:18222
void SetLogoutStartTime(time_t requestTime)
Engage the logout process for the user.
Definition: WorldSession.h:385

◆ HandleLogoutRequestOpcode()

void WorldSession::HandleLogoutRequestOpcode ( WorldPackets::Character::LogoutRequest logoutRequest)

TODO: Possibly add RBAC permission to log out in combat

Definition at line 418 of file MiscHandler.cpp.

419{
420 LOG_DEBUG("network", "WORLD: Recvd CMSG_LOGOUT_REQUEST Message, security - {}", GetSecurity());
421
422 if (ObjectGuid lguid = GetPlayer()->GetLootGUID())
423 DoLootRelease(lguid);
424
425 bool instantLogout = ((GetSecurity() >= 0 && uint32(GetSecurity()) >= sWorld->getIntConfig(CONFIG_INSTANT_LOGOUT))
427
428 bool preventAfkSanctuaryLogout = sWorld->getIntConfig(CONFIG_AFK_PREVENT_LOGOUT) == 1
429 && GetPlayer()->isAFK() && sAreaTableStore.LookupEntry(GetPlayer()->GetAreaId())->IsSanctuary();
430
431 bool preventAfkLogout = sWorld->getIntConfig(CONFIG_AFK_PREVENT_LOGOUT) == 2
432 && GetPlayer()->isAFK();
433
435 bool canLogoutInCombat = GetPlayer()->HasPlayerFlag(PLAYER_FLAGS_RESTING);
436
437 uint32 reason = 0;
438 if (GetPlayer()->IsInCombat() && !canLogoutInCombat)
439 reason = 1;
440 else if (GetPlayer()->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FALLING | MOVEMENTFLAG_FALLING_FAR))
441 reason = 3; // is jumping or falling
442 else if (preventAfkSanctuaryLogout || preventAfkLogout || GetPlayer()->duel || GetPlayer()->HasAura(9454)) // is dueling or frozen by GM via freeze command
443 reason = 2; // FIXME - Need the correct value
444
446 logoutResponse.LogoutResult = reason;
447 logoutResponse.Instant = instantLogout;
448 SendPacket(logoutResponse.Write());
449
450 if (reason)
451 {
453 return;
454 }
455
456 //instant logout in taverns/cities or on taxi or for admins, gm's, mod's if its enabled in worldserver.conf
457 if (instantLogout)
458 {
459 LogoutPlayer(true);
460 return;
461 }
462
463 // not set flags if player can't free move to prevent lost state at logout cancel
464 if (GetPlayer()->CanFreeMove())
465 {
466 if (GetPlayer()->getStandState() == UNIT_STAND_STATE_STAND)
467 {
469 }
470
471 GetPlayer()->SetRooted(true);
473 }
474
476}
@ PLAYER_FLAGS_RESTING
Definition: Player.h:480
@ MOVEMENTFLAG_FALLING
Definition: Unit.h:564
@ MOVEMENTFLAG_FALLING_FAR
Definition: Unit.h:565
@ UNIT_STAND_STATE_SIT
Definition: Unit.h:54
@ CONFIG_INSTANT_LOGOUT
Definition: IWorld.h:299
@ CONFIG_AFK_PREVENT_LOGOUT
Definition: IWorld.h:374
void SetUnitFlag(UnitFlags flags)
Definition: Unit.h:1479
WorldPacket const * Write() override

◆ HandleLootMasterGiveOpcode()

void WorldSession::HandleLootMasterGiveOpcode ( WorldPacket recvPacket)

Definition at line 406 of file LootHandler.cpp.

407{
408 uint8 slotid;
409 ObjectGuid lootguid, target_playerguid;
410
411 recvData >> lootguid >> slotid >> target_playerguid;
412
414 {
416 return;
417 }
418
419 Player* target = ObjectAccessor::GetPlayer(*_player, target_playerguid);
420 if (!target)
421 {
423 return;
424 }
425
426 LOG_DEBUG("network", "WorldSession::HandleLootMasterGiveOpcode (CMSG_LOOT_MASTER_GIVE, 0x02A3) Target = [{}].", target->GetName());
427
428 if (_player->GetLootGUID() != lootguid)
429 {
431 return;
432 }
433
434 if (!_player->IsInRaidWith(target))
435 {
437 //LOG_DEBUG("network", "MasterLootItem: Player {} tried to give an item to ineligible player {} !", GetPlayer()->GetName(), target->GetName());
438 return;
439 }
440
441 Loot* loot = nullptr;
442
443 if (GetPlayer()->GetLootGUID().IsCreatureOrVehicle())
444 {
445 Creature* creature = GetPlayer()->GetMap()->GetCreature(lootguid);
446 if (!creature)
447 return;
448
449 loot = &creature->loot;
450 }
451 else if (GetPlayer()->GetLootGUID().IsGameObject())
452 {
453 GameObject* pGO = GetPlayer()->GetMap()->GetGameObject(lootguid);
454 if (!pGO)
455 return;
456
457 loot = &pGO->loot;
458 }
459
460 if (!loot)
461 return;
462
463 if (slotid >= loot->items.size() + loot->quest_items.size())
464 {
465 LOG_DEBUG("loot", "MasterLootItem: Player {} might be using a hack! (slot {}, size {})", GetPlayer()->GetName(), slotid, (unsigned long)loot->items.size());
466 return;
467 }
468
469 LootItem& item = slotid >= loot->items.size() ? loot->quest_items[slotid - loot->items.size()] : loot->items[slotid];
470
471 ItemPosCountVec dest;
472 InventoryResult msg = target->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, item.itemid, item.count);
473 if (!item.AllowedForPlayer(target, loot->sourceWorldObjectGUID))
475 if (msg != EQUIP_ERR_OK)
476 {
479 else if (msg == EQUIP_ERR_INVENTORY_FULL)
481 else
483
484 return;
485 }
486
487 // list of players allowed to receive this item in trade
488 AllowedLooterSet looters = item.GetAllowedLooters();
489
490 // not move item from loot to target inventory
491 Item* newitem = target->StoreNewItem(dest, item.itemid, true, item.randomPropertyId, looters);
492 target->SendNewItem(newitem, uint32(item.count), false, false, true);
493 target->UpdateLootAchievements(&item, loot);
494
495 // mark as looted
496 item.count = 0;
497 item.is_looted = true;
498
499 loot->NotifyItemRemoved(slotid);
500 --loot->unlootedCount;
501}
@ EQUIP_ERR_CANT_CARRY_MORE_OF_THIS
Definition: Item.h:58
@ EQUIP_ERR_INVENTORY_FULL
Definition: Item.h:91
@ EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM
Definition: Item.h:51
GuidSet AllowedLooterSet
Definition: LootMgr.h:152
@ MASTER_LOOT
Definition: LootMgr.h:61
@ LOOT_ERROR_MASTER_OTHER
Definition: LootMgr.h:107
@ LOOT_ERROR_MASTER_INV_FULL
Definition: LootMgr.h:105
@ LOOT_ERROR_MASTER_UNIQUE_ITEM
Definition: LootMgr.h:106
@ LOOT_ERROR_PLAYER_NOT_FOUND
Definition: LootMgr.h:103
void UpdateLootAchievements(LootItem *item, Loot *loot)
void SendNewItem(Item *item, uint32 count, bool received, bool created, bool broadcast=false, bool sendChatMessage=true)
Item * StoreNewItem(ItemPosCountVec const &pos, uint32 item, bool update, int32 randomPropertyId=0)
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=nullptr) const
Definition: Player.h:1248
bool IsInRaidWith(Unit const *unit) const
Definition: Unit.cpp:18829
ObjectGuid GetMasterLooterGuid() const
Definition: Group.cpp:2261
LootMethod GetLootMethod() const
Definition: Group.cpp:2251
uint32 itemid
Definition: LootMgr.h:156
int32 randomPropertyId
Definition: LootMgr.h:159
uint8 count
Definition: LootMgr.h:163
bool is_looted
Definition: LootMgr.h:164
const AllowedLooterSet & GetAllowedLooters() const
Definition: LootMgr.h:182
bool AllowedForPlayer(Player const *player, bool isGivenByMasterLooter=false, bool allowQuestLoot=true, ObjectGuid source=ObjectGuid::Empty) const
Definition: LootMgr.cpp:407
ObjectGuid sourceWorldObjectGUID
Definition: LootMgr.h:330
uint8 unlootedCount
Definition: LootMgr.h:323
std::vector< LootItem > items
Definition: LootMgr.h:320
void NotifyItemRemoved(uint8 lootIndex)
Definition: LootMgr.cpp:728
std::vector< LootItem > quest_items
Definition: LootMgr.h:321

◆ HandleLootMethodOpcode()

void WorldSession::HandleLootMethodOpcode ( WorldPacket recvPacket)

error handling

Definition at line 481 of file GroupHandler.cpp.

482{
483 LOG_DEBUG("network", "WORLD: Received CMSG_LOOT_METHOD");
484
485 uint32 lootMethod;
486 ObjectGuid lootMaster;
487 uint32 lootThreshold;
488 recvData >> lootMethod >> lootMaster >> lootThreshold;
489
490 Group* group = GetPlayer()->GetGroup();
491 if (!group)
492 return;
493
495 // Xinef: Check if group is LFG
496 if (!group->IsLeader(GetPlayer()->GetGUID()) || group->isLFGGroup(true))
497 return;
498
499 if (lootMethod > NEED_BEFORE_GREED)
500 return;
501
502 if (lootThreshold < ITEM_QUALITY_UNCOMMON || lootThreshold > ITEM_QUALITY_ARTIFACT)
503 return;
504
505 if (lootMethod == MASTER_LOOT && !group->IsMember(lootMaster))
506 return;
507 /********************/
508
509 // everything's fine, do it
510 group->SetLootMethod((LootMethod)lootMethod);
511 group->SetMasterLooterGuid(lootMaster);
512 group->SetLootThreshold((ItemQualities)lootThreshold);
513 group->SendUpdate();
514}
LootMethod
Definition: LootMgr.h:58
@ NEED_BEFORE_GREED
Definition: LootMgr.h:63
ItemQualities
@ ITEM_QUALITY_ARTIFACT
void SetLootMethod(LootMethod method)
Definition: Group.cpp:2170
void SetLootThreshold(ItemQualities threshold)
Definition: Group.cpp:2185
void SetMasterLooterGuid(ObjectGuid guid)
Definition: Group.cpp:2180

◆ HandleLootMoneyOpcode()

void WorldSession::HandleLootMoneyOpcode ( WorldPacket recvPacket)

Definition at line 103 of file LootHandler.cpp.

104{
105 LOG_DEBUG("network", "WORLD: CMSG_LOOT_MONEY");
106
107 Player* player = GetPlayer();
108 ObjectGuid guid = player->GetLootGUID();
109 if (!guid)
110 return;
111
112 Loot* loot = nullptr;
113 bool shareMoney = true;
114
115 switch (guid.GetHigh())
116 {
117 case HighGuid::GameObject:
118 {
119 GameObject* go = GetPlayer()->GetMap()->GetGameObject(guid);
120
121 // do not check distance for GO if player is the owner of it (ex. fishing bobber)
122 if (go && ((go->GetOwnerGUID() == player->GetGUID() || go->IsWithinDistInMap(player))))
123 {
124 loot = &go->loot;
125 }
126
127 break;
128 }
129 case HighGuid::Corpse: // remove insignia ONLY in BG
130 {
131 Corpse* bones = ObjectAccessor::GetCorpse(*player, guid);
132
133 if (bones && bones->IsWithinDistInMap(player, INTERACTION_DISTANCE))
134 {
135 loot = &bones->loot;
136 shareMoney = false;
137 }
138
139 break;
140 }
141 case HighGuid::Item:
142 {
143 if (Item* item = player->GetItemByGuid(guid))
144 {
145 loot = &item->loot;
146 shareMoney = false;
147 }
148 break;
149 }
150 case HighGuid::Unit:
151 case HighGuid::Vehicle:
152 {
153 Creature* creature = player->GetMap()->GetCreature(guid);
154 bool lootAllowed = creature && creature->IsAlive() == (player->getClass() == CLASS_ROGUE && creature->loot.loot_type == LOOT_PICKPOCKETING);
155 if (lootAllowed && creature->IsWithinDistInMap(player, INTERACTION_DISTANCE))
156 {
157 loot = &creature->loot;
158 if (creature->IsAlive())
159 shareMoney = false;
160 }
161 else
162 player->SendLootError(guid, lootAllowed ? LOOT_ERROR_TOO_FAR : LOOT_ERROR_DIDNT_KILL);
163 break;
164 }
165 default:
166 return; // unlootable type
167 }
168
169 if (loot)
170 {
171 sScriptMgr->OnBeforeLootMoney(player, loot);
172 loot->NotifyMoneyRemoved();
173 if (shareMoney && player->GetGroup()) //item, pickpocket and players can be looted only single player
174 {
175 Group* group = player->GetGroup();
176
177 std::vector<Player*> playersNear;
178 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
179 {
180 Player* member = itr->GetSource();
181 if (!member)
182 continue;
183
184 if (player->IsAtLootRewardDistance(member))
185 playersNear.push_back(member);
186 }
187
188 uint32 goldPerPlayer = uint32((loot->gold) / (playersNear.size()));
189
190 for (std::vector<Player*>::const_iterator i = playersNear.begin(); i != playersNear.end(); ++i)
191 {
192 (*i)->ModifyMoney(goldPerPlayer);
193 (*i)->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, goldPerPlayer);
194
196 data << uint32(goldPerPlayer);
197 data << uint8(playersNear.size() > 1 ? 0 : 1); // Controls the text displayed in chat. 0 is "Your share is..." and 1 is "You loot..."
198 (*i)->GetSession()->SendPacket(&data);
199 }
200 }
201 else
202 {
203 player->ModifyMoney(loot->gold);
205
207 data << uint32(loot->gold);
208 data << uint8(1); // "You loot..."
209 SendPacket(&data);
210 }
211
212 sScriptMgr->OnLootMoney(player, loot->gold);
213
214 loot->gold = 0;
215
216 // Delete the money loot record from the DB
217 if (loot->containerGUID)
218 sLootItemStorage->RemoveStoredLootMoney(loot->containerGUID, loot);
219
220 // Delete container if empty
221 if (loot->isLooted() && guid.IsItem())
222 DoLootRelease(guid);
223 }
224}
#define sLootItemStorage
@ ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY
Definition: DBCEnums.h:185
@ SMSG_LOOT_MONEY_NOTIFY
Definition: Opcodes.h:385
HighGuid GetHigh() const
Definition: ObjectGuid.h:145
bool IsAtLootRewardDistance(WorldObject const *pRewardSource) const
Definition: Player.cpp:12492
ObjectGuid containerGUID
Definition: LootMgr.h:329
void NotifyMoneyRemoved()
Definition: LootMgr.cpp:744
uint32 gold
Definition: LootMgr.h:322

◆ HandleLootOpcode()

void WorldSession::HandleLootOpcode ( WorldPacket recvPacket)

Definition at line 226 of file LootHandler.cpp.

227{
228 LOG_DEBUG("network", "WORLD: CMSG_LOOT");
229
230 ObjectGuid guid;
231 recvData >> guid;
232
233 // Check possible cheat
234 if (!GetPlayer()->IsAlive() || !guid.IsCreatureOrVehicle())
235 return;
236
237 // interrupt cast
238 if (GetPlayer()->IsNonMeleeSpellCast(false))
240
242}
@ LOOT_CORPSE
Definition: LootMgr.h:81
void SendLoot(ObjectGuid guid, LootType loot_type)
Definition: Player.cpp:7637

◆ HandleLootReleaseOpcode()

void WorldSession::HandleLootReleaseOpcode ( WorldPacket recvPacket)

Definition at line 244 of file LootHandler.cpp.

245{
246 LOG_DEBUG("network", "WORLD: CMSG_LOOT_RELEASE");
247
248 // cheaters can modify lguid to prevent correct apply loot release code and re-loot
249 // use internal stored guid
250 ObjectGuid guid;
251 recvData >> guid;
252
253 if (ObjectGuid lguid = GetPlayer()->GetLootGUID())
254 if (lguid == guid)
255 DoLootRelease(lguid);
256}

◆ HandleLootRoll()

void WorldSession::HandleLootRoll ( WorldPacket recvData)

Definition at line 516 of file GroupHandler.cpp.

517{
518 ObjectGuid guid;
519 uint32 itemSlot;
520 uint8 rollType;
521 recvData >> guid; // guid of the item rolled
522 recvData >> itemSlot;
523 recvData >> rollType; // 0: pass, 1: need, 2: greed
524
525 Group* group = GetPlayer()->GetGroup();
526 if (!group)
527 return;
528
529 group->CountRollVote(GetPlayer()->GetGUID(), guid, rollType);
530
531 switch (rollType)
532 {
533 case ROLL_NEED:
535 break;
536 case ROLL_GREED:
538 break;
539 }
540}
@ ROLL_GREED
Definition: LootMgr.h:36
@ ROLL_NEED
Definition: LootMgr.h:35
@ ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED
Definition: DBCEnums.h:207
@ ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED
Definition: DBCEnums.h:206
bool CountRollVote(ObjectGuid playerGUID, ObjectGuid Guid, uint8 Choise)
Definition: Group.cpp:1328

◆ HandleMailCreateTextItem()

void WorldSession::HandleMailCreateTextItem ( WorldPacket recvData)

Definition at line 729 of file MailHandler.cpp.

730{
731 ObjectGuid mailbox;
732 uint32 mailId;
733
734 recvData >> mailbox;
735 recvData >> mailId;
736
737 if (!CanOpenMailBox(mailbox))
738 return;
739
740 Player* player = _player;
741
742 Mail* m = player->GetMail(mailId);
743 if (!m || (m->body.empty() && !m->mailTemplateId) || m->state == MAIL_STATE_DELETED || m->deliver_time > GameTime::GetGameTime().count() || (m->checked & MAIL_CHECK_MASK_COPIED))
744 {
746 return;
747 }
748
749 Item* bodyItem = new Item; // This is not bag and then can be used new Item.
750 if (!bodyItem->Create(sObjectMgr->GetGenerator<HighGuid::Item>().Generate(), MAIL_BODY_ITEM_TEMPLATE, player))
751 {
752 delete bodyItem;
753 return;
754 }
755
756 // in mail template case we need create new item text
757 if (m->mailTemplateId)
758 {
759 MailTemplateEntry const* mailTemplateEntry = sMailTemplateStore.LookupEntry(m->mailTemplateId);
760 if (!mailTemplateEntry)
761 {
763 delete bodyItem;
764 return;
765 }
766
767 bodyItem->SetText(mailTemplateEntry->content[GetSessionDbcLocale()]);
768 }
769 else
770 bodyItem->SetText(m->body);
771
774
775 LOG_DEBUG("network.opcode", "HandleMailCreateTextItem mailid={}", mailId);
776
777 ItemPosCountVec dest;
778 uint8 msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, dest, bodyItem, false);
779 if (msg == EQUIP_ERR_OK)
780 {
783 player->m_mailsUpdated = true;
784
785 player->StoreItem(dest, bodyItem, true);
787 }
788 else
789 {
791 delete bodyItem;
792 }
793}
DBCStorage< MailTemplateEntry > sMailTemplateStore(MailTemplateEntryfmt)
@ ITEM_FLAG_MAIL_TEXT_MASK
Definition: ItemTemplate.h:143
@ ITEM_FIELD_FLAGS
Definition: UpdateFields.h:42
@ ITEM_FIELD_CREATOR
Definition: UpdateFields.h:37
@ MAIL_STATE_CHANGED
Definition: Mail.h:70
#define MAIL_BODY_ITEM_TEMPLATE
Definition: Mail.h:33
@ MAIL_MADE_PERMANENT
@ MAIL_ERR_EQUIP_ERROR
@ MAIL_OK
@ MAIL_ERR_INTERNAL_ERROR
virtual bool Create(ObjectGuid::LowType guidlow, uint32 itemid, Player const *owner)
Definition: Item.cpp:284
void SetText(std::string const &text)
Definition: Item.h:300
void SetFlag(uint16 index, uint32 newFlag)
Definition: Object.cpp:845
void SetUInt32Value(uint16 index, uint32 value)
Definition: Object.cpp:650
void SendMailResult(uint32 mailId, MailResponseType mailAction, MailResponseResult mailError, uint32 equipError=0, ObjectGuid::LowType item_guid=0, uint32 item_count=0)
Definition: Player.cpp:2804
bool m_mailsUpdated
Definition: Player.h:1555
Mail * GetMail(uint32 id)
Definition: Player.cpp:3736
uint32 sender
Definition: Mail.h:173
std::string body
Definition: Mail.h:176
time_t deliver_time
Definition: Mail.h:180
uint32 checked
Definition: Mail.h:183
MailState state
Definition: Mail.h:184
uint16 mailTemplateId
Definition: Mail.h:172
LocaleConstant GetSessionDbcLocale() const
Definition: WorldSession.h:495
char const * content[16]

◆ HandleMailDelete()

void WorldSession::HandleMailDelete ( WorldPacket recvData)

Definition at line 362 of file MailHandler.cpp.

363{
364 ObjectGuid mailbox;
365 uint32 mailId;
366 recvData >> mailbox;
367 recvData >> mailId;
368 recvData.read_skip<uint32>(); // mailTemplateId
369
370 if (!CanOpenMailBox(mailbox))
371 return;
372
373 Mail* m = _player->GetMail(mailId);
374 Player* player = _player;
375 player->m_mailsUpdated = true;
376 if (m)
377 {
378 // delete shouldn't show up for COD mails
379 if (m->COD)
380 {
382 return;
383 }
384
386
387 sCharacterCache->DecreaseCharacterMailCount(player->GetGUID());
388 }
389 player->SendMailResult(mailId, MAIL_DELETED, MAIL_OK);
390}
@ MAIL_DELETED
uint32 COD
Definition: Mail.h:182

◆ HandleMailMarkAsRead()

void WorldSession::HandleMailMarkAsRead ( WorldPacket recvData)

Definition at line 339 of file MailHandler.cpp.

340{
341 ObjectGuid mailbox;
342 uint32 mailId;
343 recvData >> mailbox;
344 recvData >> mailId;
345
346 if (!CanOpenMailBox(mailbox))
347 return;
348
349 Player* player = _player;
350 Mail* m = player->GetMail(mailId);
351 if (m && m->state != MAIL_STATE_DELETED)
352 {
353 if (player->unReadMails)
354 --player->unReadMails;
356 player->m_mailsUpdated = true;
358 }
359}
@ MAIL_CHECK_MASK_READ
Definition: Mail.h:48
uint8 unReadMails
Definition: Player.h:1619

◆ HandleMailReturnToSender()

void WorldSession::HandleMailReturnToSender ( WorldPacket recvData)

Definition at line 392 of file MailHandler.cpp.

393{
394 ObjectGuid mailbox;
395 uint32 mailId;
396 recvData >> mailbox;
397 recvData >> mailId;
398 recvData.read_skip<uint64>(); // original sender GUID for return to, not used
399
400 if (!CanOpenMailBox(mailbox))
401 return;
402
403 Player* player = _player;
404 Mail* m = player->GetMail(mailId);
405 if (!m || m->state == MAIL_STATE_DELETED || m->deliver_time > GameTime::GetGameTime().count())
406 {
408 return;
409 }
410 //we can return mail now
411 //so firstly delete the old one
412 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
413
415 stmt->SetData(0, mailId);
416 trans->Append(stmt);
417
418 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_ITEM_BY_ID);
419 stmt->SetData(0, mailId);
420 trans->Append(stmt);
421
422 player->RemoveMail(mailId);
423
424 // only return mail if the player exists (and delete if not existing)
425 if (m->messageType == MAIL_NORMAL && m->sender)
426 {
427 MailDraft draft(m->subject, m->body);
428 if (m->mailTemplateId)
429 draft = MailDraft(m->mailTemplateId, false); // items already included
430
431 if (m->HasItems())
432 {
433 for (MailItemInfoVec::iterator itr2 = m->items.begin(); itr2 != m->items.end(); ++itr2)
434 {
435 Item* item = player->GetMItem(itr2->item_guid);
436 if (item)
437 draft.AddItem(item);
438
439 player->RemoveMItem(itr2->item_guid);
440 }
441 }
442 draft.AddMoney(m->money).SendReturnToSender(GetAccountId(), m->receiver, m->sender, trans);
443 }
444
445 CharacterDatabase.CommitTransaction(trans);
446
447 delete m; //we can deallocate old mail
449
450 sCharacterCache->DecreaseCharacterMailCount(player->GetGUID());
451}
@ CHAR_DEL_MAIL_BY_ID
@ CHAR_DEL_MAIL_ITEM_BY_ID
@ MAIL_RETURNED_TO_SENDER
void RemoveMail(uint32 id)
Definition: Player.cpp:2791
bool RemoveMItem(ObjectGuid::LowType itemLowGuid)
Definition: Player.h:1639
bool HasItems() const
Definition: Mail.h:207
ObjectGuid::LowType receiver
Definition: Mail.h:174
uint8 messageType
Definition: Mail.h:170
std::string subject
Definition: Mail.h:175
std::vector< MailItemInfo > items
Definition: Mail.h:177
uint32 money
Definition: Mail.h:181

◆ HandleMailTakeItem()

void WorldSession::HandleMailTakeItem ( WorldPacket recvData)

Definition at line 454 of file MailHandler.cpp.

455{
456 ObjectGuid mailbox;
457 uint32 mailId;
458 uint32 itemLowGuid;
459 recvData >> mailbox;
460 recvData >> mailId;
461 recvData >> itemLowGuid; // item guid low
462
463 if (!CanOpenMailBox(mailbox))
464 return;
465
466 Player* player = _player;
467
468 Mail* m = player->GetMail(mailId);
469 if (!m || m->state == MAIL_STATE_DELETED || m->deliver_time > GameTime::GetGameTime().count())
470 {
472 return;
473 }
474
475 // verify that the mail has the item to avoid cheaters taking COD items without paying
476 bool foundItem = false;
477 for (std::vector<MailItemInfo>::const_iterator itr = m->items.begin(); itr != m->items.end(); ++itr)
478 if (itr->item_guid == itemLowGuid)
479 {
480 foundItem = true;
481 break;
482 }
483 if (!foundItem)
484 {
486 return;
487 }
488
489 // prevent cheating with skip client money check
490 if (!player->HasEnoughMoney(m->COD))
491 {
493 return;
494 }
495
496 Item* it = player->GetMItem(itemLowGuid);
497
498 ItemPosCountVec dest;
499 uint8 msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, dest, it, false);
500 if (msg == EQUIP_ERR_OK)
501 {
502 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
503 m->RemoveItem(itemLowGuid);
504 m->removedItems.push_back(itemLowGuid);
505
506 if (m->COD > 0) // if there is COD, take COD money from player and send them to sender by mail
507 {
508 uint32 sender_accId = 0;
510 if (sender)
511 {
512 sender_accId = sender->GetSession()->GetAccountId();
513 }
514 else
515 {
516 sender_accId = sCharacterCache->GetCharacterAccountIdByGuid(ObjectGuid(HighGuid::Player, m->sender));
517 }
518
519 // check player existence
520 if (sender || sender_accId)
521 {
522 MailDraft(m->subject, "")
523 .AddMoney(m->COD)
525
526 if( m->COD >= 10 * GOLD )
527 {
528 std::string senderName;
529 if (!sCharacterCache->GetCharacterNameByGuid(ObjectGuid(HighGuid::Player, m->sender), senderName))
530 {
531 senderName = sObjectMgr->GetAcoreStringForDBCLocale(LANG_UNKNOWN);
532 }
533 std::string subj = m->subject;
535 CharacterDatabase.Execute("INSERT INTO log_money VALUES({}, {}, \"{}\", \"{}\", {}, \"{}\", {}, \"{}\", NOW(), {})",
536 GetAccountId(), player->GetGUID().GetCounter(), player->GetName(), player->GetSession()->GetRemoteAddress(), sender_accId, senderName, m->COD, subj, 1);
537 }
538 }
539
540 player->ModifyMoney(-int32(m->COD));
541 }
542
543 m->COD = 0;
545 player->m_mailsUpdated = true;
546 player->RemoveMItem(it->GetGUID().GetCounter());
547
548 uint32 count = it->GetCount(); // save counts before store and possible merge with deleting
549 it->SetState(ITEM_UNCHANGED); // need to set this state, otherwise item cannot be removed later, if neccessary
550 player->MoveItemToInventory(dest, it, true);
551
552 player->SaveInventoryAndGoldToDB(trans);
553 player->_SaveMail(trans);
554 CharacterDatabase.CommitTransaction(trans);
555
556 player->SendMailResult(mailId, MAIL_ITEM_TAKEN, MAIL_OK, 0, itemLowGuid, count);
557 }
558 else
560}
void CleanStringForMysqlQuery(std::string &str)
Definition: Common.cpp:44
@ ITEM_UNCHANGED
Definition: Item.h:203
@ MAIL_CHECK_MASK_COD_PAYMENT
This mail was copied. Do not allow making a copy of items in mail.
Definition: Mail.h:51
@ LANG_UNKNOWN
Definition: Language.h:77
@ MAIL_ITEM_TAKEN
@ MAIL_ERR_NOT_ENOUGH_MONEY
Player * FindPlayerByLowGUID(ObjectGuid::LowType lowguid)
void MoveItemToInventory(ItemPosCountVec const &dest, Item *pItem, bool update, bool in_characterInventoryDB=false)
void _SaveMail(CharacterDatabaseTransaction trans)
MailDraft & AddMoney(uint32 money)
Definition: Mail.h:138
std::vector< uint32 > removedItems
Definition: Mail.h:178
bool RemoveItem(ObjectGuid::LowType item_guid)
Definition: Mail.h:194

◆ HandleMailTakeMoney()

void WorldSession::HandleMailTakeMoney ( WorldPacket recvData)

Definition at line 562 of file MailHandler.cpp.

563{
564 ObjectGuid mailbox;
565 uint32 mailId;
566 recvData >> mailbox;
567 recvData >> mailId;
568
569 if (!CanOpenMailBox(mailbox))
570 return;
571
572 Player* player = _player;
573
574 Mail* m = player->GetMail(mailId);
575 if (!m || m->state == MAIL_STATE_DELETED || m->deliver_time > GameTime::GetGameTime().count())
576 {
578 return;
579 }
580
581 if (!player->ModifyMoney(m->money, false))
582 {
584 return;
585 }
586
587 m->money = 0;
589 player->m_mailsUpdated = true;
590
591 player->SendMailResult(mailId, MAIL_MONEY_TAKEN, MAIL_OK);
592
593 // save money and mail to prevent cheating
594 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
595 player->SaveGoldToDB(trans);
596 player->_SaveMail(trans);
597 CharacterDatabase.CommitTransaction(trans);
598}
@ MAIL_MONEY_TAKEN
void SaveGoldToDB(CharacterDatabaseTransaction trans)

◆ HandleMessagechatOpcode()

void WorldSession::HandleMessagechatOpcode ( WorldPacket recvPacket)

Definition at line 59 of file ChatHandler.cpp.

60{
61 uint32 type;
62 uint32 lang;
63
64 recvData >> type;
65 recvData >> lang;
66
67 if (type >= MAX_CHAT_MSG_TYPE)
68 {
69 LOG_ERROR("network.opcode", "CHAT: Wrong message type received: {}", type);
70 recvData.rfinish();
71 return;
72 }
73
74 if (lang == LANG_UNIVERSAL && type != CHAT_MSG_AFK && type != CHAT_MSG_DND)
75 {
76 LOG_ERROR("entities.player.cheat", "CMSG_MESSAGECHAT: Possible hacking-attempt: {} tried to send a message in universal language", GetPlayerInfo());
78 recvData.rfinish();
79 return;
80 }
81
82 Player* sender = GetPlayer();
83
84 // prevent talking at unknown language (cheating)
85 LanguageDesc const* langDesc = GetLanguageDescByID(lang);
86 if (!langDesc)
87 {
89 recvData.rfinish();
90 return;
91 }
92
93 if (langDesc->skill_id != 0 && !sender->HasSkill(langDesc->skill_id))
94 {
95 // also check SPELL_AURA_COMPREHEND_LANGUAGE (client offers option to speak in that language)
96 bool foundAura = false;
97 for (auto const& auraEff : sender->GetAuraEffectsByType(SPELL_AURA_COMPREHEND_LANGUAGE))
98 {
99 if (auraEff->GetMiscValue() == int32(lang))
100 {
101 foundAura = true;
102 break;
103 }
104 }
105
106 if (!foundAura)
107 {
109 recvData.rfinish();
110 return;
111 }
112 }
113
114 // pussywizard: chatting on most chat types requires 2 hours played to prevent spam/abuse
116 {
117 switch (type)
118 {
119 case CHAT_MSG_ADDON:
120 case CHAT_MSG_PARTY:
121 case CHAT_MSG_RAID:
122 case CHAT_MSG_GUILD:
123 case CHAT_MSG_OFFICER:
124 case CHAT_MSG_AFK:
125 case CHAT_MSG_DND:
131 break;
132 default:
133 {
134 if (sWorld->getBoolConfig(CONFIG_CHAT_MUTE_FIRST_LOGIN))
135 {
136 uint32 minutes = sWorld->getIntConfig(CONFIG_CHAT_TIME_MUTE_FIRST_LOGIN);
137
138 if (sender->GetTotalPlayedTime() < minutes * MINUTE)
139 {
141 recvData.rfinish();
142 return;
143 }
144 }
145 }
146 }
147 }
148
149 // pussywizard:
150 switch (type)
151 {
152 case CHAT_MSG_SAY:
153 case CHAT_MSG_YELL:
154 case CHAT_MSG_EMOTE:
156 case CHAT_MSG_AFK:
157 case CHAT_MSG_DND:
158 if (sender->IsSpectator())
159 {
160 recvData.rfinish();
161 return;
162 }
163 }
164
165 if (sender->HasAura(1852) && type != CHAT_MSG_WHISPER)
166 {
168 recvData.rfinish();
169 return;
170 }
171
172 if (lang == LANG_ADDON)
173 {
174 // LANG_ADDON is only valid for the following message types
175 switch (type)
176 {
177 case CHAT_MSG_PARTY:
178 case CHAT_MSG_RAID:
179 case CHAT_MSG_GUILD:
181 case CHAT_MSG_WHISPER:
182 // check if addon messages are disabled
183 if (!sWorld->getBoolConfig(CONFIG_ADDON_CHANNEL))
184 {
185 recvData.rfinish();
186 return;
187 }
188 break;
189 default:
190 LOG_ERROR("network", "Player {} ({}) sent a chatmessage with an invalid language/message type combination",
191 GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString());
192
193 recvData.rfinish();
194 return;
195 }
196 }
197 else
198 {
199 // send in universal language if player in .gmon mode (ignore spell effects)
200 if (sender->IsGameMaster())
201 lang = LANG_UNIVERSAL;
202 else
203 {
204 // send in universal language in two side iteration allowed mode
206 lang = LANG_UNIVERSAL;
207 else
208 {
209 switch (type)
210 {
211 case CHAT_MSG_PARTY:
213 case CHAT_MSG_RAID:
216 // allow two side chat at group channel if two side group allowed
218 lang = LANG_UNIVERSAL;
219 break;
220 case CHAT_MSG_GUILD:
221 case CHAT_MSG_OFFICER:
222 // allow two side chat at guild channel if two side guild allowed
224 lang = LANG_UNIVERSAL;
225 break;
226 }
227 }
228 // but overwrite it by SPELL_AURA_MOD_LANGUAGE auras (only single case used)
230 if (!ModLangAuras.empty())
231 lang = ModLangAuras.front()->GetMiscValue();
232 }
233
234 if (type != CHAT_MSG_AFK && type != CHAT_MSG_DND)
236 }
237
238 std::string to, channel, msg;
239 bool ignoreChecks = false;
240 switch (type)
241 {
242 case CHAT_MSG_SAY:
243 case CHAT_MSG_EMOTE:
244 case CHAT_MSG_YELL:
245 case CHAT_MSG_PARTY:
247 case CHAT_MSG_GUILD:
248 case CHAT_MSG_OFFICER:
249 case CHAT_MSG_RAID:
254 msg = recvData.ReadCString(lang != LANG_ADDON);
255 break;
256 case CHAT_MSG_WHISPER:
257 recvData >> to;
258 msg = recvData.ReadCString(lang != LANG_ADDON);
259 break;
260 case CHAT_MSG_CHANNEL:
261 recvData >> channel;
262 msg = recvData.ReadCString(lang != LANG_ADDON);
263 break;
264 case CHAT_MSG_AFK:
265 case CHAT_MSG_DND:
266 msg = recvData.ReadCString(lang != LANG_ADDON);
267 ignoreChecks = true;
268 break;
269 }
270
271 // Our Warden module also uses SendAddonMessage as a way to communicate Lua check results to the server, see if this is that
272 if (type == CHAT_MSG_GUILD && lang == LANG_ADDON && _warden && _warden->ProcessLuaCheckResponse(msg))
273 {
274 return;
275 }
276
277 // pussywizard:
278 if (msg.length() > 255 || (lang != LANG_ADDON && msg.find("|0") != std::string::npos))
279 return;
280
281 if (!ignoreChecks)
282 {
283 if (msg.empty())
284 return;
285
286 if (ChatHandler(this).ParseCommands(msg.c_str()))
287 return;
288
289 if (!_player->CanSpeak())
290 {
291 std::string timeStr = secsToTimeString(m_muteTime - GameTime::GetGameTime().count());
293 return;
294 }
295 }
296
297 // do message validity checks
298 if (lang != LANG_ADDON)
299 {
300 // cut at the first newline or carriage return
301 std::string::size_type pos = msg.find_first_of("\n\r");
302
303 if (pos == 0)
304 {
305 return;
306 }
307 else if (pos != std::string::npos)
308 {
309 msg.erase(pos);
310 }
311
312 // abort on any sort of nasty character
313 for (uint8 c : msg)
314 {
315 if (isNasty(c))
316 {
317 LOG_ERROR("network", "Player {} {} sent a message containing invalid character {} - blocked", GetPlayer()->GetName(),
318 GetPlayer()->GetGUID().ToString(), uint8(c));
319 return;
320 }
321 }
322
323 // collapse multiple spaces into one
325 {
326 auto end = std::unique(msg.begin(), msg.end(), [](char c1, char c2) { return (c1 == ' ') && (c2 == ' '); });
327 msg.erase(end, msg.end());
328 }
329
330 // Validate hyperlinks
332 {
333 return;
334 }
335 }
336
337 else
338 {
340 }
341
342 sScriptMgr->OnBeforeSendChatMessage(_player, type, lang, msg);
343
344 switch (type)
345 {
346 case CHAT_MSG_SAY:
347 case CHAT_MSG_EMOTE:
348 case CHAT_MSG_YELL:
349 {
350 // Prevent cheating
351 if (!sender->IsAlive())
352 return;
353
354 if (sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_SAY_LEVEL_REQ))
355 {
357 return;
358 }
359
360 if (type == CHAT_MSG_SAY)
361 sender->Say(msg, Language(lang));
362 else if (type == CHAT_MSG_EMOTE)
363 sender->TextEmote(msg);
364 else if (type == CHAT_MSG_YELL)
365 sender->Yell(msg, Language(lang));
366 }
367 break;
368 case CHAT_MSG_WHISPER:
369 {
370 if (sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ))
371 {
373 return;
374 }
375
376 if (!normalizePlayerName(to))
377 {
379 break;
380 }
381
382 Player* receiver = ObjectAccessor::FindPlayerByName(to, false);
383 bool senderIsPlayer = AccountMgr::IsPlayerAccount(GetSecurity());
384 bool receiverIsPlayer = AccountMgr::IsPlayerAccount(receiver ? receiver->GetSession()->GetSecurity() : SEC_PLAYER);
385 if (!receiver || (senderIsPlayer && !receiverIsPlayer && !receiver->isAcceptWhispers() && !receiver->IsInWhisperWhiteList(sender->GetGUID())))
386 {
388 return;
389 }
390
391 if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT) && senderIsPlayer && receiverIsPlayer)
392 if (GetPlayer()->GetTeamId() != receiver->GetTeamId())
393 {
395 return;
396 }
397
398 // pussywizard: optimization
399 if (GetPlayer()->HasAura(1852) && !receiver->IsGameMaster())
400 {
402 return;
403 }
404
405 // If player is a Gamemaster and doesn't accept whisper, we auto-whitelist every player that the Gamemaster is talking to
406 if (!senderIsPlayer && !sender->isAcceptWhispers() && !sender->IsInWhisperWhiteList(receiver->GetGUID()))
407 sender->AddWhisperWhiteList(receiver->GetGUID());
408
409 GetPlayer()->Whisper(msg, Language(lang), receiver);
410 }
411 break;
412 case CHAT_MSG_PARTY:
414 {
415 // if player is in battleground, he cannot say to battleground members by /p
416 Group* group = GetPlayer()->GetOriginalGroup();
417 if (!group)
418 {
419 group = sender->GetGroup();
420 if (!group || group->isBGGroup())
421 return;
422 }
423
424 if (type == CHAT_MSG_PARTY_LEADER && !group->IsLeader(sender->GetGUID()))
425 return;
426
427 if (!sScriptMgr->CanPlayerUseChat(GetPlayer(), type, lang, msg, group))
428 {
429 return;
430 }
431
432 sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
433
434 WorldPacket data;
435 ChatHandler::BuildChatPacket(data, ChatMsg(type), Language(lang), sender, nullptr, msg);
436 group->BroadcastPacket(&data, false, group->GetMemberGroup(GetPlayer()->GetGUID()));
437 }
438 break;
439 case CHAT_MSG_GUILD:
440 {
441 if (GetPlayer()->GetGuildId())
442 {
443 if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId()))
444 {
445 if (!sScriptMgr->CanPlayerUseChat(GetPlayer(), type, lang, msg, guild))
446 {
447 return;
448 }
449
450 sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, guild);
451
452 guild->BroadcastToGuild(this, false, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
453 }
454 }
455 }
456 break;
457 case CHAT_MSG_OFFICER:
458 {
459 if (GetPlayer()->GetGuildId())
460 {
461 if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId()))
462 {
463 if (!sScriptMgr->CanPlayerUseChat(GetPlayer(), type, lang, msg, guild))
464 {
465 return;
466 }
467
468 sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, guild);
469
470 guild->BroadcastToGuild(this, true, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
471 }
472 }
473 }
474 break;
475 case CHAT_MSG_RAID:
476 {
477 // if player is in battleground, he cannot say to battleground members by /ra
478 Group* group = GetPlayer()->GetOriginalGroup();
479 if (!group)
480 {
481 group = GetPlayer()->GetGroup();
482 if (!group || group->isBGGroup() || !group->isRaidGroup())
483 return;
484 }
485
486 if (!sScriptMgr->CanPlayerUseChat(GetPlayer(), type, lang, msg, group))
487 {
488 return;
489 }
490
491 sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
492
493 WorldPacket data;
494 ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID, Language(lang), sender, nullptr, msg);
495 group->BroadcastPacket(&data, false);
496 }
497 break;
499 {
500 // if player is in battleground, he cannot say to battleground members by /ra
501 Group* group = GetPlayer()->GetOriginalGroup();
502 if (!group)
503 {
504 group = GetPlayer()->GetGroup();
505 if (!group || group->isBGGroup() || !group->isRaidGroup() || !group->IsLeader(sender->GetGUID()))
506 return;
507 }
508
509 if (!sScriptMgr->CanPlayerUseChat(GetPlayer(), type, lang, msg, group))
510 {
511 return;
512 }
513
514 sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
515
516 WorldPacket data;
517 ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_LEADER, Language(lang), sender, nullptr, msg);
518 group->BroadcastPacket(&data, false);
519 }
520 break;
522 {
523 Group* group = GetPlayer()->GetGroup();
524 if (!group || !group->isRaidGroup() || !(group->IsLeader(GetPlayer()->GetGUID()) || group->IsAssistant(GetPlayer()->GetGUID())) || group->isBGGroup())
525 return;
526
527 if (!sScriptMgr->CanPlayerUseChat(GetPlayer(), type, lang, msg, group))
528 {
529 return;
530 }
531
532 sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
533
534 // In battleground, raid warning is sent only to players in battleground - code is ok
535 WorldPacket data;
536 ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_WARNING, Language(lang), sender, nullptr, msg);
537 group->BroadcastPacket(&data, false);
538 }
539 break;
541 {
542 //battleground raid is always in Player->GetGroup(), never in GetOriginalGroup()
543 Group* group = GetPlayer()->GetGroup();
544 if (!group || !group->isBGGroup())
545 return;
546
547 if (!sScriptMgr->CanPlayerUseChat(GetPlayer(), type, lang, msg, group))
548 {
549 return;
550 }
551
552 sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
553
554 WorldPacket data;
555 ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND, Language(lang), sender, nullptr, msg);
556 group->BroadcastPacket(&data, false);
557 }
558 break;
560 {
561 // battleground raid is always in Player->GetGroup(), never in GetOriginalGroup()
562 Group* group = GetPlayer()->GetGroup();
563 if (!group || !group->isBGGroup() || !group->IsLeader(GetPlayer()->GetGUID()))
564 return;
565
566 if (!sScriptMgr->CanPlayerUseChat(GetPlayer(), type, lang, msg, group))
567 {
568 return;
569 }
570
571 sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
572
573 WorldPacket data;
574 ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND_LEADER, Language(lang), sender, nullptr, msg);
575 group->BroadcastPacket(&data, false);
576 }
577 break;
578 case CHAT_MSG_CHANNEL:
579 {
581 {
582 if (sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ))
583 {
585 return;
586 }
587 }
588
589 if (ChannelMgr* cMgr = ChannelMgr::forTeam(sender->GetTeamId()))
590 {
591 if (Channel* chn = cMgr->GetChannel(channel, sender))
592 {
593 if (!sScriptMgr->CanPlayerUseChat(sender, type, lang, msg, chn))
594 {
595 return;
596 }
597
598 sScriptMgr->OnPlayerChat(sender, type, lang, msg, chn);
599
600 chn->Say(sender->GetGUID(), msg.c_str(), lang);
601 }
602 }
603 }
604 break;
605 case CHAT_MSG_AFK:
606 {
607 if (!sender->IsInCombat())
608 {
609 if (sender->isAFK()) // Already AFK
610 {
611 if (msg.empty())
612 sender->ToggleAFK(); // Remove AFK
613 else
614 sender->autoReplyMsg = msg; // Update message
615 }
616 else // New AFK mode
617 {
618 sender->autoReplyMsg = msg.empty() ? GetAcoreString(LANG_PLAYER_AFK_DEFAULT) : msg;
619
620 if (sender->isDND())
621 sender->ToggleDND();
622
623 sender->ToggleAFK();
624 }
625
626 if (!sScriptMgr->CanPlayerUseChat(sender, type, lang, msg))
627 {
628 return;
629 }
630
631 sScriptMgr->OnPlayerChat(sender, type, lang, msg);
632 }
633 break;
634 }
635 case CHAT_MSG_DND:
636 {
637 if (sender->isDND()) // Already DND
638 {
639 if (msg.empty())
640 sender->ToggleDND(); // Remove DND
641 else
642 sender->autoReplyMsg = msg; // Update message
643 }
644 else // New DND mode
645 {
646 sender->autoReplyMsg = msg.empty() ? GetAcoreString(LANG_PLAYER_DND_DEFAULT) : msg;
647
648 if (sender->isAFK())
649 sender->ToggleAFK();
650
651 sender->ToggleDND();
652 }
653
654 if (!sScriptMgr->CanPlayerUseChat(sender, type, lang, msg))
655 {
656 return;
657 }
658
659 sScriptMgr->OnPlayerChat(sender, type, lang, msg);
660
661 break;
662 }
663 default:
664 LOG_ERROR("network.opcode", "CHAT: unknown message type {}, lang: {}", type, lang);
665 break;
666 }
667}
@ SEC_PLAYER
Definition: Common.h:66
std::string secsToTimeString(uint64 timeInSecs, bool shortText)
Definition: Util.cpp:74
LanguageDesc const * GetLanguageDescByID(uint32 lang)
Definition: ObjectMgr.cpp:251
bool isNasty(uint8 c)
Definition: ChatHandler.cpp:44
@ LANG_SAY_REQ
Definition: Language.h:1154
@ LANG_GM_SILENCE
Definition: Language.h:1169
@ LANG_UNKNOWN_LANGUAGE
Definition: Language.h:716
@ LANG_NOT_LEARNED_LANGUAGE
Definition: Language.h:717
@ LANG_WHISPER_REQ
Definition: Language.h:1155
@ LANG_WAIT_BEFORE_SPEAKING
Definition: Language.h:650
@ LANG_PLAYER_AFK_DEFAULT
Definition: Language.h:655
@ LANG_MUTED_PLAYER
Definition: Language.h:1313
@ LANG_PLAYER_DND_DEFAULT
Definition: Language.h:654
@ LANG_CHANNEL_REQ
Definition: Language.h:1156
@ SPELL_AURA_COMPREHEND_LANGUAGE
@ SPELL_AURA_MOD_LANGUAGE
@ CONFIG_CHAT_CHANNEL_LEVEL_REQ
Definition: IWorld.h:284
@ CONFIG_CHAT_WHISPER_LEVEL_REQ
Definition: IWorld.h:285
@ CONFIG_CHAT_TIME_MUTE_FIRST_LOGIN
Definition: IWorld.h:288
@ CONFIG_CHAT_SAY_LEVEL_REQ
Definition: IWorld.h:286
@ CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT
Definition: IWorld.h:78
@ CONFIG_CHAT_MUTE_FIRST_LOGIN
Definition: IWorld.h:106
@ CONFIG_CHAT_FAKE_MESSAGE_PREVENTING
Definition: IWorld.h:105
@ CONFIG_ADDON_CHANNEL
Definition: IWorld.h:72
ChatMsg
@ CHAT_MSG_RAID_WARNING
@ CHAT_MSG_RAID
@ CHAT_MSG_TEXT_EMOTE
@ CHAT_MSG_SAY
@ CHAT_MSG_PARTY_LEADER
@ CHAT_MSG_RAID_LEADER
@ CHAT_MSG_DND
@ CHAT_MSG_YELL
@ CHAT_MSG_PARTY
@ CHAT_MSG_WHISPER
@ CHAT_MSG_EMOTE
@ CHAT_MSG_GUILD
@ CHAT_MSG_OFFICER
@ CHAT_MSG_AFK
@ CHAT_MSG_ADDON
@ CHAT_MSG_BATTLEGROUND
@ CHAT_MSG_BATTLEGROUND_LEADER
@ CHAT_MSG_CHANNEL
Language
@ LANG_ADDON
#define MAX_CHAT_MSG_TYPE
bool CanSpeak() const
Definition: PlayerMisc.cpp:69
bool IsInWhisperWhiteList(ObjectGuid guid)
Definition: Player.cpp:15579
std::string autoReplyMsg
Definition: Player.h:1117
uint32 GetTotalPlayedTime()
Definition: Player.h:1162
bool HasSkill(uint32 skill) const
Definition: Player.cpp:5317
void ToggleAFK()
Definition: Player.cpp:1272
void UpdateSpeakTime(ChatFloodThrottle::Index index)
Definition: PlayerMisc.cpp:29
void AddWhisperWhiteList(ObjectGuid guid)
Definition: Player.h:2504
bool isAcceptWhispers() const
Definition: Player.h:1134
void Yell(std::string_view text, Language language, WorldObject const *=nullptr) override
Handles yelled message in regular chat based on declared language and in config pre-defined Range.
Definition: Player.cpp:9215
void Say(std::string_view text, Language language, WorldObject const *=nullptr) override
Handles said message in regular chat based on declared language and in config pre-defined Range.
Definition: Player.cpp:9195
void TextEmote(std::string_view text, WorldObject const *=nullptr, bool=false) override
Outputs an universal text which is supposed to be an action.
Definition: Player.cpp:9236
void Whisper(std::string_view text, Language language, Player *receiver, bool=false) override
Handles whispers from Addons and players based on sender, receiver's guid and language.
Definition: Player.cpp:9265
void ToggleDND()
Definition: Player.cpp:1281
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition: Unit.h:1964
std::list< AuraEffect * > AuraEffectList
Definition: Unit.h:1306
uint32 skill_id
Definition: ObjectMgr.h:698
void BroadcastPacket(WorldPacket const *packet, bool ignorePlayersInBGRaid, int group=-1, ObjectGuid ignore=ObjectGuid::Empty)
Definition: Group.cpp:1726
void SendPlayerNotFoundNotice(std::string const &name)
void SendWrongFactionNotice()
std::unique_ptr< Warden > _warden

◆ HandleMinimapPingOpcode()

void WorldSession::HandleMinimapPingOpcode ( WorldPacket recvData)

error handling

Definition at line 542 of file GroupHandler.cpp.

543{
544 LOG_DEBUG("network", "WORLD: Received MSG_MINIMAP_PING");
545
546 if (!GetPlayer()->GetGroup())
547 return;
548
549 float x, y;
550 recvData >> x;
551 recvData >> y;
552
554 /********************/
555
556 // everything's fine, do it
557 WorldPacket data(MSG_MINIMAP_PING, (8 + 4 + 4));
558 data << GetPlayer()->GetGUID();
559 data << float(x);
560 data << float(y);
561 GetPlayer()->GetGroup()->BroadcastPacket(&data, true, -1, GetPlayer()->GetGUID());
562}
@ MSG_MINIMAP_PING
Definition: Opcodes.h:499

◆ HandleMirrorImageDataRequest()

void WorldSession::HandleMirrorImageDataRequest ( WorldPacket recvData)

Definition at line 661 of file SpellHandler.cpp.

662{
663 LOG_DEBUG("network", "WORLD: CMSG_GET_MIRRORIMAGE_DATA");
664 ObjectGuid guid;
665 recvData >> guid;
666
667 // Get unit for which data is needed by client
668 Unit* unit = ObjectAccessor::GetUnit(*_player, guid);
669 if (!unit)
670 return;
671
673 return;
674
675 // Get creator of the unit (SPELL_AURA_CLONE_CASTER does not stack)
676 Unit* creator = unit->GetAuraEffectsByType(SPELL_AURA_CLONE_CASTER).front()->GetCaster();
677 if (!creator)
678 return;
679
681 data << guid;
682 data << uint32(creator->GetDisplayId());
683 data << uint8(creator->getRace());
684 data << uint8(creator->getGender());
685 data << uint8(creator->getClass());
686
687 if (creator->GetTypeId() == TYPEID_PLAYER)
688 {
689 Player* player = creator->ToPlayer();
690 data << uint8(player->GetByteValue(PLAYER_BYTES, 0)); // skin
691 data << uint8(player->GetByteValue(PLAYER_BYTES, 1)); // face
692 data << uint8(player->GetByteValue(PLAYER_BYTES, 2)); // hair
693 data << uint8(player->GetByteValue(PLAYER_BYTES, 3)); // haircolor
694 data << uint8(player->GetByteValue(PLAYER_BYTES_2, 0)); // facialhair
695 data << uint32(player->GetGuildId()); // unk
696
697 static EquipmentSlots const itemSlots[] =
698 {
711 };
712
713 // Display items in visible slots
714 for (EquipmentSlots const* itr = &itemSlots[0]; *itr != EQUIPMENT_SLOT_END; ++itr)
715 {
717 data << uint32(0);
718 else if (*itr == EQUIPMENT_SLOT_BACK && player->HasPlayerFlag(PLAYER_FLAGS_HIDE_CLOAK))
719 data << uint32(0);
720 else if (Item const* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, *itr))
721 {
722 uint32 displayInfoId = item->GetTemplate()->DisplayInfoID;
723
724 sScriptMgr->OnGlobalMirrorImageDisplayItem(item, displayInfoId);
725
726 data << uint32(displayInfoId);
727 }
728 else
729 data << uint32(0);
730 }
731 }
732 else
733 {
734 // Skip player data for creatures
735 data << uint8(0);
736 data << uint32(0);
737 data << uint32(0);
738 data << uint32(0);
739 data << uint32(0);
740 data << uint32(0);
741 data << uint32(0);
742 data << uint32(0);
743 data << uint32(0);
744 data << uint32(0);
745 data << uint32(0);
746 data << uint32(0);
747 data << uint32(0);
748 data << uint32(0);
749 }
750
751 SendPacket(&data);
752}
@ PLAYER_FLAGS_HIDE_CLOAK
Definition: Player.h:486
@ PLAYER_FLAGS_HIDE_HELM
Definition: Player.h:485
EquipmentSlots
Definition: Player.h:674
@ EQUIPMENT_SLOT_SHOULDERS
Definition: Player.h:678
@ EQUIPMENT_SLOT_BODY
Definition: Player.h:679
@ EQUIPMENT_SLOT_HANDS
Definition: Player.h:685
@ EQUIPMENT_SLOT_TABARD
Definition: Player.h:694
@ EQUIPMENT_SLOT_HEAD
Definition: Player.h:676
@ EQUIPMENT_SLOT_LEGS
Definition: Player.h:682
@ EQUIPMENT_SLOT_BACK
Definition: Player.h:690
@ EQUIPMENT_SLOT_WAIST
Definition: Player.h:681
@ EQUIPMENT_SLOT_FEET
Definition: Player.h:683
@ EQUIPMENT_SLOT_CHEST
Definition: Player.h:680
@ EQUIPMENT_SLOT_WRISTS
Definition: Player.h:684
@ SPELL_AURA_CLONE_CASTER
@ SMSG_MIRRORIMAGE_DATA
Definition: Opcodes.h:1056
uint8 GetByteValue(uint16 index, uint8 offset) const
Definition: Object.cpp:323
bool HasAuraType(AuraType auraType) const
Definition: Unit.cpp:5605

◆ HandleMountSpecialAnimOpcode()

void WorldSession::HandleMountSpecialAnimOpcode ( WorldPacket recvdata)

Definition at line 750 of file MovementHandler.cpp.

751{
753 data << GetPlayer()->GetGUID();
754
755 GetPlayer()->SendMessageToSet(&data, false);
756}
@ SMSG_MOUNTSPECIAL_ANIM
Definition: Opcodes.h:400
void SendMessageToSet(WorldPacket const *data, bool self) const override
Definition: Player.h:1975

◆ HandleMoveHoverAck()

void WorldSession::HandleMoveHoverAck ( WorldPacket recvData)

Definition at line 793 of file MovementHandler.cpp.

794{
795 LOG_DEBUG("network", "CMSG_MOVE_HOVER_ACK");
796
797 ObjectGuid guid;
798 recvData >> guid.ReadAsPacked();
799
800 recvData.read_skip<uint32>(); // unk
801
802 MovementInfo movementInfo;
803 movementInfo.guid = guid;
804 ReadMovementInfo(recvData, &movementInfo);
805
806 recvData.read_skip<uint32>(); // unk2
807}

◆ HandleMoveKnockBackAck()

void WorldSession::HandleMoveKnockBackAck ( WorldPacket recvPacket)

Definition at line 758 of file MovementHandler.cpp.

759{
760 LOG_DEBUG("network", "CMSG_MOVE_KNOCK_BACK_ACK");
761
762 ObjectGuid guid;
763 recvData >> guid.ReadAsPacked();
764
765 // pussywizard: typical check for incomming movement packets
767 {
768 recvData.rfinish(); // prevent warnings spam
769 return;
770 }
771
772 recvData.read_skip<uint32>(); // unk
773
774 MovementInfo movementInfo;
775 movementInfo.guid = guid;
776 ReadMovementInfo(recvData, &movementInfo);
777
778 _player->m_mover->m_movementInfo = movementInfo;
779
781 data << guid.WriteAsPacked();
783 _player->SetCanTeleport(true);
784 // knockback specific info
785 data << movementInfo.jump.sinAngle;
786 data << movementInfo.jump.cosAngle;
787 data << movementInfo.jump.xyspeed;
788 data << movementInfo.jump.zspeed;
789
790 _player->SendMessageToSet(&data, false);
791}
@ MSG_MOVE_KNOCK_BACK
Definition: Opcodes.h:271
void BuildMovementPacket(ByteBuffer *data) const
Definition: Unit.cpp:19910

◆ HandleMovementOpcodes()

void WorldSession::HandleMovementOpcodes ( WorldPacket recvPacket)

Definition at line 334 of file MovementHandler.cpp.

335{
336 uint16 opcode = recvData.GetOpcode();
337
338 Unit* mover = _player->m_mover;
339
340 ASSERT(mover); // there must always be a mover
341
342 Player* plrMover = mover->ToPlayer();
343
344 // ignore, waiting processing in WorldSession::HandleMoveWorldportAckOpcode and WorldSession::HandleMoveTeleportAck
345 if (plrMover && plrMover->IsBeingTeleported())
346 {
347 recvData.rfinish(); // prevent warnings spam
348 return;
349 }
350
351 /* extract packet */
352 ObjectGuid guid;
353 recvData >> guid.ReadAsPacked();
354
355 // prevent tampered movement data
356 if (!guid || guid != mover->GetGUID())
357 {
358 recvData.rfinish(); // prevent warnings spam
359 return;
360 }
361
362 // pussywizard: typical check for incomming movement packets | prevent tampered movement data
363 if (!mover || !(mover->IsInWorld()) || mover->IsDuringRemoveFromWorld() || guid != mover->GetGUID())
364 {
365 recvData.rfinish(); // prevent warnings spam
366 return;
367 }
368
369 MovementInfo movementInfo;
370 movementInfo.guid = guid;
371 ReadMovementInfo(recvData, &movementInfo);
372
373 if (!movementInfo.pos.IsPositionValid())
374 {
375 if (plrMover)
376 {
377 sScriptMgr->AnticheatSetSkipOnePacketForASH(plrMover, true);
378 sScriptMgr->AnticheatUpdateMovementInfo(plrMover, movementInfo);
379 }
380
381 recvData.rfinish(); // prevent warnings spam
382 return;
383 }
384
385 if (!mover->movespline->Finalized())
386 {
387 recvData.rfinish(); // prevent warnings spam
388 return;
389 }
390
391 // Xinef: do not allow to move with UNIT_FLAG_DISABLE_MOVE
393 {
394 // Xinef: skip moving packets
396 {
397 if (plrMover)
398 {
399 sScriptMgr->AnticheatSetSkipOnePacketForASH(plrMover, true);
400 sScriptMgr->AnticheatUpdateMovementInfo(plrMover, movementInfo);
401 }
402 return;
403 }
404 movementInfo.pos.Relocate(mover->GetPositionX(), mover->GetPositionY(), mover->GetPositionZ());
405
406 if (mover->GetTypeId() == TYPEID_UNIT)
407 {
408 movementInfo.transport.guid = mover->m_movementInfo.transport.guid;
410 movementInfo.transport.seat = mover->m_movementInfo.transport.seat;
411 }
412 }
413
415 {
416 // We were teleported, skip packets that were broadcast before teleport
417 if (movementInfo.pos.GetExactDist2d(mover) > SIZE_OF_GRIDS)
418 {
419 if (plrMover)
420 {
421 sScriptMgr->AnticheatSetSkipOnePacketForASH(plrMover, true);
422 sScriptMgr->AnticheatUpdateMovementInfo(plrMover, movementInfo);
423 //LOG_INFO("anticheat", "MovementHandler:: 2 We were teleported, skip packets that were broadcast before teleport");
424 }
425 recvData.rfinish(); // prevent warnings spam
426 return;
427 }
428
429 if (!Acore::IsValidMapCoord(movementInfo.pos.GetPositionX() + movementInfo.transport.pos.GetPositionX(), movementInfo.pos.GetPositionY() + movementInfo.transport.pos.GetPositionY(),
430 movementInfo.pos.GetPositionZ() + movementInfo.transport.pos.GetPositionZ(), movementInfo.pos.GetOrientation() + movementInfo.transport.pos.GetOrientation()))
431 {
432 if (plrMover)
433 {
434 sScriptMgr->AnticheatSetSkipOnePacketForASH(plrMover, true);
435 sScriptMgr->AnticheatUpdateMovementInfo(plrMover, movementInfo);
436 }
437
438 recvData.rfinish(); // prevent warnings spam
439 return;
440 }
441
442 // if we boarded a transport, add us to it
443 if (plrMover)
444 {
445 if (!plrMover->GetTransport())
446 {
447 if (Transport* transport = plrMover->GetMap()->GetTransport(movementInfo.transport.guid))
448 {
449 plrMover->m_transport = transport;
450 transport->AddPassenger(plrMover);
451 }
452 }
453 else if (plrMover->GetTransport()->GetGUID() != movementInfo.transport.guid)
454 {
455 sScriptMgr->AnticheatSetSkipOnePacketForASH(plrMover, true);
456
457 bool foundNewTransport = false;
458 plrMover->m_transport->RemovePassenger(plrMover);
459 if (Transport* transport = plrMover->GetMap()->GetTransport(movementInfo.transport.guid))
460 {
461 foundNewTransport = true;
462 plrMover->m_transport = transport;
463 transport->AddPassenger(plrMover);
464 }
465
466 if (!foundNewTransport)
467 {
468 plrMover->m_transport = nullptr;
469 movementInfo.transport.Reset();
470 }
471 }
472 }
473
474 if (!mover->GetTransport() && !mover->GetVehicle())
475 {
476 GameObject* go = mover->GetMap()->GetGameObject(movementInfo.transport.guid);
477 if (!go || go->GetGoType() != GAMEOBJECT_TYPE_TRANSPORT)
478 {
480 }
481 }
482 }
483 else if (plrMover && plrMover->GetTransport()) // if we were on a transport, leave
484 {
485 sScriptMgr->AnticheatSetUnderACKmount(plrMover); // just for safe
486
487 plrMover->m_transport->RemovePassenger(plrMover);
488 plrMover->m_transport = nullptr;
489 movementInfo.transport.Reset();
490 }
491
492 // fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map).
493 if (opcode == MSG_MOVE_FALL_LAND && plrMover && !plrMover->IsInFlight())
494 {
495 plrMover->HandleFall(movementInfo);
496
497 sScriptMgr->AnticheatSetJumpingbyOpcode(plrMover, false);
498 }
499
500 // interrupt parachutes upon falling or landing in water
501 if (opcode == MSG_MOVE_FALL_LAND || opcode == MSG_MOVE_START_SWIM)
502 {
504
505 if (plrMover)
506 {
507 sScriptMgr->AnticheatSetJumpingbyOpcode(plrMover, false);
508 }
509 }
510
511 if (plrMover && ((movementInfo.flags & MOVEMENTFLAG_SWIMMING) != 0) != plrMover->IsInWater())
512 {
513 // now client not include swimming flag in case jumping under water
514 plrMover->SetInWater(!plrMover->IsInWater() || plrMover->GetMap()->IsUnderWater(plrMover->GetPhaseMask(), movementInfo.pos.GetPositionX(),
515 movementInfo.pos.GetPositionY(), movementInfo.pos.GetPositionZ(), plrMover->GetCollisionHeight()));
516 }
517
518 if (plrMover)//Hook for OnPlayerMove
519 {
520 sScriptMgr->OnPlayerMove(plrMover, movementInfo, opcode);
521 }
522
523 bool jumpopcode = false;
524 if (opcode == MSG_MOVE_JUMP)
525 {
526 jumpopcode = true;
527 if (plrMover && !sScriptMgr->AnticheatHandleDoubleJump(plrMover, mover))
528 {
529 plrMover->GetSession()->KickPlayer();
530 return;
531 }
532 }
533
534 /* start some hack detection */
535 if (plrMover && !sScriptMgr->AnticheatCheckMovementInfo(plrMover, movementInfo, mover, jumpopcode))
536 {
537 plrMover->GetSession()->KickPlayer();
538 return;
539 }
540
541 /* process position-change */
542 WorldPacket data(opcode, recvData.size());
543 int64 movementTime = (int64)movementInfo.time + _timeSyncClockDelta;
544 if (_timeSyncClockDelta == 0 || movementTime < 0 || movementTime > 0xFFFFFFFF)
545 {
546 LOG_INFO("misc", "The computed movement time using clockDelta is erronous. Using fallback instead");
547 movementInfo.time = getMSTime();
548 }
549 else
550 {
551 movementInfo.time = (uint32) movementTime;
552 }
553
554 movementInfo.guid = mover->GetGUID();
555 WriteMovementInfo(&data, &movementInfo);
556 mover->SendMessageToSet(&data, _player);
557
558 mover->m_movementInfo = movementInfo;
559
560 // Some vehicles allow the passenger to turn by himself
561 if (Vehicle* vehicle = mover->GetVehicle())
562 {
563 if (VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(mover))
564 {
565 if (seat->m_flags & VEHICLE_SEAT_FLAG_ALLOW_TURNING && movementInfo.pos.GetOrientation() != mover->GetOrientation())
566 {
567 mover->SetOrientation(movementInfo.pos.GetOrientation());
569 }
570 }
571
572 return;
573 }
574
575 mover->UpdatePosition(movementInfo.pos);
576
577 if (plrMover) // nothing is charmed, or player charmed
578 {
579 if (plrMover->IsSitState() && (movementInfo.flags & (MOVEMENTFLAG_MASK_MOVING | MOVEMENTFLAG_MASK_TURNING)))
581
582 plrMover->UpdateFallInformationIfNeed(movementInfo, opcode);
583
584 if (movementInfo.pos.GetPositionZ() < plrMover->GetMap()->GetMinHeight(movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY()))
585 if (!plrMover->GetBattleground() || !plrMover->GetBattleground()->HandlePlayerUnderMap(_player))
586 {
587 if (plrMover->IsAlive())
588 {
590 plrMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, GetPlayer()->GetMaxHealth());
591 // player can be alive if GM
592 if (plrMover->IsAlive())
593 plrMover->KillPlayer();
594 }
595 else if (!plrMover->HasPlayerFlag(PLAYER_FLAGS_IS_OUT_OF_BOUNDS))
596 {
597 GraveyardStruct const* grave = sGraveyard->GetClosestGraveyard(plrMover, plrMover->GetTeamId());
598 if (grave)
599 {
600 plrMover->TeleportTo(grave->Map, grave->x, grave->y, grave->z, plrMover->GetOrientation());
601 plrMover->Relocate(grave->x, grave->y, grave->z, plrMover->GetOrientation());
602 }
603 }
604 }
605 }
606}
#define SIZE_OF_GRIDS
Definition: MapDefines.h:13
uint32 getMSTime()
Definition: Timer.h:103
@ DAMAGE_FALL_TO_VOID
Definition: Player.h:833
@ PLAYER_FLAGS_IS_OUT_OF_BOUNDS
Definition: Player.h:489
@ MOVEMENTFLAG_ONTRANSPORT
Definition: Unit.h:561
@ MOVEMENTFLAG_MASK_MOVING
Definition: Unit.h:585
@ MOVEMENTFLAG_MASK_TURNING
Definition: Unit.h:590
@ MOVEMENTFLAG_SWIMMING
Definition: Unit.h:573
@ UNIT_FLAG_DISABLE_MOVE
Definition: Unit.h:450
#define sGraveyard
Definition: GameGraveyard.h:75
@ AURA_INTERRUPT_FLAG_TURNING
Definition: SpellDefines.h:48
@ AURA_INTERRUPT_FLAG_LANDING
Definition: SpellDefines.h:69
@ VEHICLE_SEAT_FLAG_ALLOW_TURNING
Definition: DBCEnums.h:459
@ GAMEOBJECT_TYPE_TRANSPORT
@ MSG_MOVE_START_SWIM
Definition: Opcodes.h:232
@ MSG_MOVE_JUMP
Definition: Opcodes.h:217
@ MSG_MOVE_FALL_LAND
Definition: Opcodes.h:231
bool IsValidMapCoord(float c)
Definition: GridDefines.h:216
virtual bool HandlePlayerUnderMap(Player *)
Definition: Battleground.h:546
uint32 time
Definition: Object.h:270
void RemoveMovementFlag(uint32 flag)
Definition: Object.h:321
uint32 flags
Definition: Object.h:267
bool HasMovementFlag(uint32 flag) const
Definition: Object.h:322
Position pos
Definition: Object.h:269
uint32 GetPhaseMask() const
Definition: Object.h:434
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition: Object.h:482
Transport * m_transport
Definition: Object.h:639
float GetExactDist2d(const float x, const float y) const
Definition: Position.h:166
bool IsPositionValid() const
Definition: Position.cpp:175
void SetOrientation(float orientation)
Definition: Position.h:112
void Relocate(float x, float y)
Definition: Position.h:73
void HandleFall(MovementInfo const &movementInfo)
Definition: Player.cpp:13538
void SetPlayerFlag(PlayerFlags flags)
Definition: Player.h:1091
uint32 EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
Definition: Player.cpp:754
void KillPlayer()
Definition: Player.cpp:4436
void SetInWater(bool apply)
Definition: Player.cpp:2127
bool IsInWater() const override
Definition: Player.h:1099
void UpdateFallInformationIfNeed(MovementInfo const &minfo, uint16 opcode)
bool IsBeingTeleported() const
Definition: Player.h:2040
virtual void RemovePassenger(WorldObject *passenger, bool withAll=false)=0
virtual void AddPassenger(WorldObject *passenger, bool withAll=false)=0
Movement::MoveSpline * movespline
Definition: Unit.h:2435
float GetCollisionHeight() const override
Return collision height sent to client.
Definition: Unit.cpp:21110
bool HasUnitFlag(UnitFlags flags) const
Definition: Unit.h:1478
virtual bool UpdatePosition(float x, float y, float z, float ang, bool teleport=false)
Definition: Unit.cpp:20031
bool IsSitState() const
Definition: Unit.cpp:16797
bool IsUnderWater(uint32 phaseMask, float x, float y, float z, float collisionHeight) const
Definition: Map.cpp:2501
float GetMinHeight(float x, float y) const
Definition: Map.cpp:2088
Transport * GetTransport(ObjectGuid const guid)
Definition: Map.cpp:3305
bool Finalized() const
Definition: MoveSpline.h:116
void WriteMovementInfo(WorldPacket *data, MovementInfo *mi)

◆ HandleMoveNotActiveMover()

void WorldSession::HandleMoveNotActiveMover ( WorldPacket recvData)

Definition at line 729 of file MovementHandler.cpp.

730{
731 LOG_DEBUG("network", "WORLD: Recvd CMSG_MOVE_NOT_ACTIVE_MOVER");
732
733 ObjectGuid old_mover_guid;
734 recvData >> old_mover_guid.ReadAsPacked();
735
736 // pussywizard: typical check for incomming movement packets
738 {
739 recvData.rfinish(); // prevent warnings spam
740 return;
741 }
742
743 MovementInfo mi;
744 mi.guid = old_mover_guid;
745 ReadMovementInfo(recvData, &mi);
746
748}

◆ HandleMoveRootAck()

void WorldSession::HandleMoveRootAck ( WorldPacket recvPacket)

Definition at line 951 of file MovementHandler.cpp.

952{
953 ObjectGuid guid;
954 recvData >> guid.ReadAsPacked();
955
956 Unit* mover = _player->m_mover;
957 if (!mover || guid != mover->GetGUID())
958 {
959 recvData.rfinish(); // prevent warnings spam
960 return;
961 }
962
963 uint32 movementCounter;
964 recvData >> movementCounter;
965
966 MovementInfo movementInfo;
967 movementInfo.guid = guid;
968 ReadMovementInfo(recvData, &movementInfo);
969
970 /* process position-change */
971 int64 movementTime = (int64) movementInfo.time + _timeSyncClockDelta;
972 if (_timeSyncClockDelta == 0 || movementTime < 0 || movementTime > 0xFFFFFFFF)
973 {
974 LOG_INFO("misc", "The computed movement time using clockDelta is erronous. Using fallback instead");
975 movementInfo.time = getMSTime();
976 }
977 else
978 {
979 movementInfo.time = (uint32)movementTime;
980 }
981
982 movementInfo.guid = mover->GetGUID();
983 mover->m_movementInfo = movementInfo;
984 mover->UpdatePosition(movementInfo.pos);
985
986 WorldPacket data(MSG_MOVE_ROOT, 64);
987 WriteMovementInfo(&data, &movementInfo);
988 mover->SendMessageToSet(&data, _player);
989}
@ MSG_MOVE_ROOT
Definition: Opcodes.h:266

◆ HandleMoveSetCanFlyAckOpcode()

void WorldSession::HandleMoveSetCanFlyAckOpcode ( WorldPacket recvData)

Definition at line 1554 of file MiscHandler.cpp.

1555{
1556 // fly mode on/off
1557 LOG_DEBUG("network", "WORLD: CMSG_MOVE_SET_CAN_FLY_ACK");
1558
1559 ObjectGuid guid;
1560 recv_data >> guid.ReadAsPacked();
1561
1562 if (!_player)
1563 {
1564 recv_data.rfinish(); // prevent warnings spam
1565 return;
1566 }
1567
1568 recv_data.read_skip<uint32>(); // unk
1569
1570 MovementInfo movementInfo;
1571 movementInfo.guid = guid;
1572 ReadMovementInfo(recv_data, &movementInfo);
1573
1574 recv_data.read_skip<float>(); // unk2
1575
1576 sScriptMgr->AnticheatSetCanFlybyServer(_player, movementInfo.HasMovementFlag(MOVEMENTFLAG_CAN_FLY));
1577
1578 _player->m_mover->m_movementInfo.flags = movementInfo.GetMovementFlags();
1579}
@ MOVEMENTFLAG_CAN_FLY
Definition: Unit.h:576

◆ HandleMoveSplineDoneOpcode()

void WorldSession::HandleMoveSplineDoneOpcode ( WorldPacket recvPacket)

Definition at line 210 of file TaxiHandler.cpp.

211{
212 LOG_DEBUG("network", "WORLD: Received CMSG_MOVE_SPLINE_DONE");
213
214 ObjectGuid guid; // used only for proper packet read
215 recvData >> guid.ReadAsPacked();
216
217 MovementInfo movementInfo; // used only for proper packet read
218 movementInfo.guid = guid;
219 ReadMovementInfo(recvData, &movementInfo);
220
221 recvData.read_skip<uint32>(); // spline id
222
223 // in taxi flight packet received in 2 case:
224 // 1) end taxi path in far (multi-node) flight
225 // 2) switch from one map to other in case multim-map taxi path
226 // we need process only (1)
227
229 if (curDest)
230 {
231 TaxiNodesEntry const* curDestNode = sTaxiNodesStore.LookupEntry(curDest);
232
233 // far teleport case
234 if (curDestNode && curDestNode->map_id != GetPlayer()->GetMapId() && GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE)
235 {
236 if (FlightPathMovementGenerator* flight = dynamic_cast<FlightPathMovementGenerator*>(GetPlayer()->GetMotionMaster()->top()))
237 {
238 // short preparations to continue flight
239 flight->SetCurrentNodeAfterTeleport();
240 TaxiPathNodeEntry const* node = flight->GetPath()[flight->GetCurrentNode()];
241 flight->SkipCurrentNode();
242
243 GetPlayer()->TeleportTo(curDestNode->map_id, node->x, node->y, node->z, GetPlayer()->GetOrientation(), TELE_TO_NOT_LEAVE_TAXI);
244 }
245 }
246
247 return;
248 }
249
250 // at this point only 1 node is expected (final destination)
251 if (GetPlayer()->m_taxi.GetPath().size() != 1)
252 {
253 return;
254 }
255
257 GetPlayer()->SetFallInformation(GameTime::GetGameTime().count(), GetPlayer()->GetPositionZ());
258 if (GetPlayer()->pvpInfo.IsHostile)
259 {
260 GetPlayer()->CastSpell(GetPlayer(), 2479, true);
261 }
262}
DBCStorage< TaxiNodesEntry > sTaxiNodesStore(TaxiNodesEntryfmt)
@ TELE_TO_NOT_LEAVE_TAXI
Definition: Player.h:821
@ FLIGHT_MOTION_TYPE
Definition: MotionMaster.h:45
void SetFallInformation(uint32 time, float z)
Definition: Player.h:2284
PlayerTaxi m_taxi
Definition: Player.h:1123
void CleanupAfterTaxiFlight()
Definition: Player.cpp:10157
uint32 GetTaxiDestination() const
Definition: PlayerTaxi.h:65

◆ HandleMoveTeleportAck()

void WorldSession::HandleMoveTeleportAck ( WorldPacket recvPacket)

Definition at line 266 of file MovementHandler.cpp.

267{
268 LOG_DEBUG("network", "MSG_MOVE_TELEPORT_ACK");
269
270 ObjectGuid guid;
271 recvData >> guid.ReadAsPacked();
272
273 uint32 flags, time;
274 recvData >> flags >> time; // unused
275 LOG_DEBUG("network.opcode", "Guid {}", guid.ToString());
276 LOG_DEBUG("network.opcode", "Flags {}, time {}", flags, time / IN_MILLISECONDS);
277
278 Player* plMover = _player->m_mover->ToPlayer();
279
280 if (!plMover || !plMover->IsBeingTeleportedNear())
281 return;
282
283 if (guid != plMover->GetGUID())
284 return;
285
286 plMover->SetSemaphoreTeleportNear(0);
287
288 uint32 old_zone = plMover->GetZoneId();
289
290 WorldLocation const& dest = plMover->GetTeleportDest();
291 Position oldPos(*plMover);
292
293 plMover->UpdatePosition(dest, true);
294
295 // xinef: teleport pets if they are not unsummoned
296 if (Pet* pet = plMover->GetPet())
297 {
298 if (!pet->IsWithinDist3d(plMover, plMover->GetMap()->GetVisibilityRange() - 5.0f))
299 pet->NearTeleportTo(plMover->GetPositionX(), plMover->GetPositionY(), plMover->GetPositionZ(), pet->GetOrientation());
300 }
301
302 if (oldPos.GetExactDist2d(plMover) > 100.0f)
303 {
304 uint32 newzone, newarea;
305 plMover->GetZoneAndAreaId(newzone, newarea);
306 plMover->UpdateZone(newzone, newarea);
307
308 // new zone
309 if (old_zone != newzone)
310 {
311 // honorless target
312 if (plMover->pvpInfo.IsHostile)
313 plMover->CastSpell(plMover, 2479, true);
314
315 // in friendly area
316 else if (plMover->IsPvP() && !plMover->HasPlayerFlag(PLAYER_FLAGS_IN_PVP))
317 plMover->UpdatePvP(false, false);
318 }
319 }
320
321 // resummon pet
323
324 //lets process all delayed operations on successful teleport
326
328
329 // pussywizard: client forgets about losing control, resend it
330 if (plMover->HasUnitState(UNIT_STATE_FLEEING | UNIT_STATE_CONFUSED) || plMover->IsCharmed()) // only in such cases SetClientControl(self, false) is sent
331 plMover->SetClientControl(plMover, false, true);
332}
constexpr auto IN_MILLISECONDS
Definition: Common.h:62
@ PLAYER_FLAGS_IN_PVP
Definition: Player.h:484
@ UNIT_STATE_CONFUSED
Definition: Unit.h:336
@ UNIT_STATE_FLEEING
Definition: Unit.h:332
void GetZoneAndAreaId(uint32 &zoneid, uint32 &areaid) const
Definition: Object.cpp:3074
bool IsHostile
Definition: Player.h:361
WorldLocation & GetTeleportDest()
Definition: Player.h:2039
void UpdatePvP(bool state, bool _override=false)
void UpdateZone(uint32 newZone, uint32 newArea)
void ProcessDelayedOperations()
Definition: Player.cpp:1595
bool UpdatePosition(float x, float y, float z, float orientation, bool teleport=false) override
void SetSemaphoreTeleportNear(time_t tm)
Definition: Player.h:2043
PvPInfo pvpInfo
Definition: Player.h:1796
bool IsBeingTeleportedNear() const
Definition: Player.h:2041
void SetClientControl(Unit *target, bool allowMove, bool packetOnly=false)
Definition: Player.cpp:12564
void ResummonPetTemporaryUnSummonedIfAny()
Definition: Player.cpp:13923
bool IsCharmed() const
Definition: Unit.h:1868
MotionMaster * GetMotionMaster()
Definition: Unit.h:2257
float GetVisibilityRange() const
Definition: Map.h:350
void ReinitializeMovement()

◆ HandleMoveTimeSkippedOpcode()

void WorldSession::HandleMoveTimeSkippedOpcode ( WorldPacket recvData)

Definition at line 849 of file MovementHandler.cpp.

850{
851 LOG_DEBUG("network", "WORLD: Recvd CMSG_MOVE_TIME_SKIPPED");
852
853 ObjectGuid guid;
854 uint32 timeSkipped;
855 recvData >> guid.ReadAsPacked();
856 recvData >> timeSkipped;
857
858 Unit* mover = GetPlayer()->m_mover;
859
860 if (!mover)
861 {
862 LOG_ERROR("network.opcode", "WorldSession::HandleMoveTimeSkippedOpcode wrong mover state from the unit moved by the player [{}]", GetPlayer()->GetGUID().ToString());
863 return;
864 }
865
866 // prevent tampered movement data
867 if (guid != mover->GetGUID())
868 {
869 LOG_ERROR("network.opcode", "WorldSession::HandleMoveTimeSkippedOpcode wrong guid from the unit moved by the player [{}]", GetPlayer()->GetGUID().ToString());
870 return;
871 }
872
873 mover->m_movementInfo.time += timeSkipped;
874
875 WorldPacket data(MSG_MOVE_TIME_SKIPPED, recvData.size());
876 data << guid.WriteAsPacked();
877 data << timeSkipped;
878 GetPlayer()->SendMessageToSet(&data, false);
879}
@ MSG_MOVE_TIME_SKIPPED
Definition: Opcodes.h:823

◆ HandleMoveUnRootAck()

void WorldSession::HandleMoveUnRootAck ( WorldPacket recvPacket)

Definition at line 991 of file MovementHandler.cpp.

992{
993 ObjectGuid guid;
994 recvData >> guid.ReadAsPacked();
995
996 Unit* mover = _player->m_mover;
997 if (!mover || guid != mover->GetGUID())
998 {
999 recvData.rfinish(); // prevent warnings spam
1000 return;
1001 }
1002
1003 uint32 movementCounter;
1004 recvData >> movementCounter;
1005
1006 MovementInfo movementInfo;
1007 movementInfo.guid = guid;
1008 ReadMovementInfo(recvData, &movementInfo);
1009
1010 /* process position-change */
1011 int64 movementTime = (int64) movementInfo.time + _timeSyncClockDelta;
1012 if (_timeSyncClockDelta == 0 || movementTime < 0 || movementTime > 0xFFFFFFFF)
1013 {
1014 LOG_INFO("misc", "The computed movement time using clockDelta is erronous. Using fallback instead");
1015 movementInfo.time = getMSTime();
1016 }
1017 else
1018 {
1019 movementInfo.time = (uint32)movementTime;
1020 }
1021
1022 if (G3D::fuzzyEq(movementInfo.fallTime, 0.f))
1023 {
1025 }
1026
1027 movementInfo.guid = mover->GetGUID();
1028 mover->m_movementInfo = movementInfo;
1029 mover->UpdatePosition(movementInfo.pos);
1030
1031 WorldPacket data(MSG_MOVE_UNROOT, 64);
1032 WriteMovementInfo(&data, &movementInfo);
1033 mover->SendMessageToSet(&data, _player);
1034}
@ MSG_MOVE_UNROOT
Definition: Opcodes.h:267
uint32 fallTime
Definition: Object.h:295

◆ HandleMoveWaterWalkAck()

void WorldSession::HandleMoveWaterWalkAck ( WorldPacket recvPacket)

Definition at line 809 of file MovementHandler.cpp.

810{
811 LOG_DEBUG("network", "CMSG_MOVE_WATER_WALK_ACK");
812
813 ObjectGuid guid;
814 recvData >> guid.ReadAsPacked();
815
816 recvData.read_skip<uint32>(); // unk
817
818 MovementInfo movementInfo;
819 movementInfo.guid = guid;
820 ReadMovementInfo(recvData, &movementInfo);
821
822 recvData.read_skip<uint32>(); // unk2
823}

◆ HandleMoveWorldportAck()

void WorldSession::HandleMoveWorldportAck ( )

Definition at line 50 of file MovementHandler.cpp.

51{
52 // ignore unexpected far teleports
53 if (!GetPlayer()->IsBeingTeleportedFar())
54 return;
55
57
58 // get the teleport destination
59 WorldLocation const& loc = GetPlayer()->GetTeleportDest();
60
61 // possible errors in the coordinate validity check
63 {
64 KickPlayer("!MapMgr::IsValidMapCoord(loc)");
65 return;
66 }
67
68 // get the destination map entry, not the current one, this will fix homebind and reset greeting
69 MapEntry const* mEntry = sMapStore.LookupEntry(loc.GetMapId());
70 InstanceTemplate const* mInstance = sObjectMgr->GetInstanceTemplate(loc.GetMapId());
71
72 Map* oldMap = GetPlayer()->GetMap();
73 if (GetPlayer()->IsInWorld())
74 {
75 LOG_ERROR("network.opcode", "Player (Name {}) is still in world when teleported from map {} to new map {}", GetPlayer()->GetName(), oldMap->GetId(), loc.GetMapId());
76 oldMap->RemovePlayerFromMap(GetPlayer(), false);
77 }
78
79 // reset instance validity, except if going to an instance inside an instance
80 if (!GetPlayer()->m_InstanceValid && !mInstance)
81 {
82 GetPlayer()->m_InstanceValid = true;
83 // pussywizard: m_InstanceValid can be false only by leaving a group in an instance => so remove temp binds that could not be removed because player was still on the map!
84 if (!sInstanceSaveMgr->PlayerIsPermBoundToInstance(GetPlayer()->GetGUID(), oldMap->GetId(), oldMap->GetDifficulty()))
85 sInstanceSaveMgr->PlayerUnbindInstance(GetPlayer()->GetGUID(), oldMap->GetId(), oldMap->GetDifficulty(), true);
86 }
87
88 // relocate the player to the teleport destination
89 Map* newMap = sMapMgr->CreateMap(loc.GetMapId(), GetPlayer());
90 // the CanEnter checks are done in TeleporTo but conditions may change
91 // while the player is in transit, for example the map may get full
92 if (!newMap || newMap->CannotEnter(GetPlayer(), false))
93 {
94 LOG_ERROR("network.opcode", "Map {} could not be created for player {}, porting player to homebind", loc.GetMapId(), GetPlayer()->GetGUID().ToString());
95 GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->m_homebindO);
96 return;
97 }
98
99 float z = loc.GetPositionZ() + GetPlayer()->GetHoverHeight();
100 GetPlayer()->Relocate(loc.GetPositionX(), loc.GetPositionY(), z, loc.GetOrientation());
101
102 GetPlayer()->ResetMap();
103 GetPlayer()->SetMap(newMap);
104
106
108 if (!GetPlayer()->GetMap()->AddPlayerToMap(GetPlayer()))
109 {
110 LOG_ERROR("network.opcode", "WORLD: failed to teleport player {} ({}) to map {} because of unknown reason!",
111 GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString(), loc.GetMapId());
112 GetPlayer()->ResetMap();
113 GetPlayer()->SetMap(oldMap);
114 GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->m_homebindO);
115 return;
116 }
117
118 oldMap->AfterPlayerUnlinkFromMap();
119
120 // pussywizard: transport teleport couldn't teleport us to the same map (some other teleport pending, reqs not met, etc.), but we still have transport set until player moves! clear it if map differs (crashfix)
121 if (Transport* t = _player->GetTransport())
122 if (!t->IsInMap(_player))
123 {
124 t->RemovePassenger(_player);
125 _player->m_transport = nullptr;
128 }
129
131 _player->getHostileRefMgr().deleteReferences(true); // pussywizard: multithreading crashfix
132
133 CellCoord pair(Acore::ComputeCellCoord(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY()));
134 Cell cell(pair);
135 if (!GridCoord(cell.GridX(), cell.GridY()).IsCoordValid())
136 {
137 KickPlayer("!GridCoord(cell.GridX(), cell.GridY()).IsCoordValid()");
138 return;
139 }
140 newMap->LoadGrid(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY());
141
142 // pussywizard: player supposed to enter bg map
143 if (_player->InBattleground())
144 {
145 // but landed on another map, cleanup data
146 if (!mEntry->IsBattlegroundOrArena())
148 // everything ok
149 else if (Battleground* bg = _player->GetBattleground())
150 {
151 if (_player->IsInvitedForBattlegroundInstance()) // GMs are not invited, so they are not added to participants
152 bg->AddPlayer(_player);
153 }
154 }
155
156 // pussywizard: arena spectator stuff
157 {
158 if (newMap->IsBattleArena() && ((BattlegroundMap*)newMap)->GetBG() && _player->HasPendingSpectatorForBG(((BattlegroundMap*)newMap)->GetInstanceId()))
159 {
161 _player->SetIsSpectator(true);
163 ((BattlegroundMap*)newMap)->GetBG()->AddSpectator(_player);
165 }
166 else
167 _player->SetIsSpectator(false);
168
170
171 if (uint32 inviteInstanceId = _player->GetPendingSpectatorInviteInstanceId())
172 {
173 if (Battleground* tbg = sBattlegroundMgr->GetBattleground(inviteInstanceId, BATTLEGROUND_TYPE_NONE))
174 tbg->RemoveToBeTeleported(_player->GetGUID());
176 }
177 }
178
179 // xinef: do this again, player can be teleported inside bg->AddPlayer(_player)!!!!
180 CellCoord pair2(Acore::ComputeCellCoord(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY()));
181 Cell cell2(pair2);
182 if (!GridCoord(cell2.GridX(), cell2.GridY()).IsCoordValid())
183 {
184 KickPlayer("!GridCoord(cell2.GridX(), cell2.GridY()).IsCoordValid()");
185 return;
186 }
187 newMap->LoadGrid(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY());
188
190
191 // flight fast teleport case
192 if (GetPlayer()->IsInFlight())
193 {
194 if (!GetPlayer()->InBattleground())
195 {
196 // short preparations to continue flight
197 MovementGenerator* movementGenerator = GetPlayer()->GetMotionMaster()->top();
198 movementGenerator->Initialize(GetPlayer());
199 return;
200 }
201
202 // battleground state prepare, stop flight
205 }
206
207 // resurrect character at enter into instance where his corpse exist after add to map
208 Corpse* corpse = GetPlayer()->GetMap()->GetCorpseByPlayer(GetPlayer()->GetGUID());
209 if (corpse && corpse->GetType() != CORPSE_BONES)
210 {
211 if (mEntry->IsDungeon())
212 {
213 GetPlayer()->ResurrectPlayer(0.5f);
215 }
216 }
217
218 if (!corpse && mEntry->IsDungeon())
219 {
220 // resurrect character upon entering instance when the corpse is not available anymore
221 if (GetPlayer()->GetCorpseLocation().GetMapId() == mEntry->MapID)
222 {
223 GetPlayer()->ResurrectPlayer(0.5f);
225 }
226 }
227
228 bool allowMount = !mEntry->IsDungeon() || mEntry->IsBattlegroundOrArena();
229 if (mInstance)
230 {
231 Difficulty diff = GetPlayer()->GetDifficulty(mEntry->IsRaid());
232 if (MapDifficulty const* mapDiff = GetMapDifficultyData(mEntry->MapID, diff))
233 if (mapDiff->resetTime)
234 if (time_t timeReset = sInstanceSaveMgr->GetResetTimeFor(mEntry->MapID, diff))
235 {
236 uint32 timeleft = uint32(timeReset - GameTime::GetGameTime().count());
237 GetPlayer()->SendInstanceResetWarning(mEntry->MapID, diff, timeleft, true);
238 }
239 allowMount = mInstance->AllowMount;
240 }
241
242 // mount allow check
243 if (!allowMount)
245
246 // update zone immediately, otherwise leave channel will cause crash in mtmap
247 uint32 newzone, newarea;
248 GetPlayer()->GetZoneAndAreaId(newzone, newarea);
249 GetPlayer()->UpdateZone(newzone, newarea);
250
251 // honorless target
252 if (GetPlayer()->pvpInfo.IsHostile)
253 GetPlayer()->CastSpell(GetPlayer(), 2479, true);
254
255 // in friendly area
256 else if (GetPlayer()->IsPvP() && !GetPlayer()->HasPlayerFlag(PLAYER_FLAGS_IN_PVP))
257 GetPlayer()->UpdatePvP(false, false);
258
259 // resummon pet
261
262 //lets process all delayed operations on successful teleport
264}
#define SPECTATOR_ADDON_PREFIX
MapDifficulty const * GetMapDifficultyData(uint32 mapId, Difficulty difficulty)
Definition: DBCStores.cpp:749
@ CORPSE_BONES
Definition: Corpse.h:28
CoordPair< MAX_NUMBER_OF_GRIDS > GridCoord
Definition: GridDefines.h:169
@ BATTLEGROUND_TYPE_NONE
CellCoord ComputeCellCoord(float x, float y)
Definition: GridDefines.h:191
AC_GAME_API void HandleResetCommand(Player *player)
void SendCommand(T *o, Format &&fmt, Args &&... args)
bool IsEmpty() const
Definition: LinkedList.h:97
void deleteReferences(bool removeFromMap=false)
CorpseType GetType() const
Definition: Corpse.h:72
void UpdatePositionData()
Definition: Object.cpp:1154
bool HasPendingSpectatorForBG(uint32 bgInstanceId) const
Definition: Player.h:2525
void SendInitialPacketsAfterAddToMap()
Definition: Player.cpp:11345
bool m_InstanceValid
Definition: Player.h:2385
void SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint32 time, bool onEnterMap)
Definition: Player.cpp:11447
bool IsInvitedForBattlegroundInstance() const
Definition: Player.h:2205
Difficulty GetDifficulty(bool isRaid) const
Definition: Player.h:1869
void SendInitialPacketsBeforeAddToMap()
Definition: Player.cpp:11288
void ResetMap() override
Definition: Player.cpp:14354
void RemoveCorpse()
Definition: Player.cpp:4557
void ClearReceivedSpectatorResetFor()
Definition: Player.h:2529
void SetPendingSpectatorInviteInstanceId(uint32 bgInstanceId)
Definition: Player.h:2526
void SetIsSpectator(bool on)
Definition: Player.cpp:15045
void SetSemaphoreTeleportFar(time_t tm)
Definition: Player.h:2044
void SetMap(Map *map) override
Definition: Player.cpp:14366
void SetPendingSpectatorForBG(uint32 bgInstanceId)
Definition: Player.h:2524
uint32 GetPendingSpectatorInviteInstanceId() const
Definition: Player.h:2527
HostileRefMgr & getHostileRefMgr()
Definition: Unit.h:2146
float GetHoverHeight() const
Definition: Unit.h:2382
Definition: Cell.h:46
bool AllowMount
Definition: Map.h:276
virtual void RemovePlayerFromMap(Player *, bool)
Definition: Map.cpp:914
void LoadGrid(float x, float y)
Definition: Map.cpp:494
virtual void AfterPlayerUnlinkFromMap()
Definition: Map.cpp:937
virtual EnterState CannotEnter(Player *, bool)
Definition: Map.h:437
uint32 GetId() const
Definition: Map.h:378
Corpse * GetCorpseByPlayer(ObjectGuid const &ownerGuid) const
Definition: Map.h:532
Difficulty GetDifficulty() const
Definition: Map.h:442
static bool IsValidMapCoord(uint32 mapid, Position const &pos)
Definition: MapMgr.h:91
_Ty top() const
Definition: MotionMaster.h:148
void MovementExpired(bool reset=true)
Definition: MotionMaster.h:178
virtual void Initialize(Unit *)=0
uint32 MapID
bool IsBattlegroundOrArena() const
bool IsDungeon() const

◆ HandleMoveWorldportAckOpcode()

void WorldSession::HandleMoveWorldportAckOpcode ( WorldPacket recvPacket)

Definition at line 44 of file MovementHandler.cpp.

45{
46 LOG_DEBUG("network", "WORLD: got MSG_MOVE_WORLDPORT_ACK.");
48}
void HandleMoveWorldportAck()

◆ HandleNameQueryOpcode()

void WorldSession::HandleNameQueryOpcode ( WorldPacket recvPacket)

Definition at line 67 of file QueryHandler.cpp.

68{
69 ObjectGuid guid;
70 recvData >> guid;
71
72 // This is disable by default to prevent lots of console spam
73 // LOG_INFO("network.opcode", "HandleNameQueryOpcode {}", guid);
74
76}
void SendNameQueryOpcode(ObjectGuid guid)

◆ HandleNextCinematicCamera()

void WorldSession::HandleNextCinematicCamera ( WorldPacket recvPacket)

Definition at line 989 of file MiscHandler.cpp.

990{
991{
992 LOG_DEBUG("network", "WORLD: Received CMSG_NEXT_CINEMATIC_CAMERA");
993}
994 // Sent by client when cinematic actually begun. So we begin the server side process
996}
void BeginCinematic()

◆ HandleNpcTextQueryOpcode()

void WorldSession::HandleNpcTextQueryOpcode ( WorldPacket recvPacket)

Definition at line 270 of file QueryHandler.cpp.

271{
272 uint32 textID;
273 ObjectGuid guid;
274
275 recvData >> textID;
276 LOG_DEBUG("network", "WORLD: CMSG_NPC_TEXT_QUERY TextId: {}", textID);
277
278 recvData >> guid;
279
280 GossipText const* gossip = sObjectMgr->GetGossipText(textID);
281
282 WorldPacket data(SMSG_NPC_TEXT_UPDATE, 100); // guess size
283 data << textID;
284
285 if (!gossip)
286 {
287 for (uint8 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i)
288 {
289 data << float(0);
290 data << "Greetings $N";
291 data << "Greetings $N";
292 data << uint32(0);
293 data << uint32(0);
294 data << uint32(0);
295 data << uint32(0);
296 data << uint32(0);
297 data << uint32(0);
298 data << uint32(0);
299 }
300 }
301 else
302 {
303 std::string text0[MAX_GOSSIP_TEXT_OPTIONS], text1[MAX_GOSSIP_TEXT_OPTIONS];
305
306 for (uint8 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i)
307 {
308 BroadcastText const* bct = sObjectMgr->GetBroadcastText(gossip->Options[i].BroadcastTextID);
309 if (bct)
310 {
311 text0[i] = bct->GetText(locale, GENDER_MALE, true);
312 text1[i] = bct->GetText(locale, GENDER_FEMALE, true);
313 }
314 else
315 {
316 text0[i] = gossip->Options[i].Text_0;
317 text1[i] = gossip->Options[i].Text_1;
318 }
319
320 if (locale != DEFAULT_LOCALE && !bct)
321 {
322 if (NpcTextLocale const* npcTextLocale = sObjectMgr->GetNpcTextLocale(textID))
323 {
324 ObjectMgr::GetLocaleString(npcTextLocale->Text_0[i], locale, text0[i]);
325 ObjectMgr::GetLocaleString(npcTextLocale->Text_1[i], locale, text1[i]);
326 }
327 }
328
329 data << gossip->Options[i].Probability;
330
331 if (text0[i].empty())
332 data << text1[i];
333 else
334 data << text0[i];
335
336 if (text1[i].empty())
337 data << text0[i];
338 else
339 data << text1[i];
340
341 data << gossip->Options[i].Language;
342
343 for (uint8 j = 0; j < MAX_GOSSIP_TEXT_EMOTES; ++j)
344 {
345 data << gossip->Options[i].Emotes[j]._Delay;
346 data << gossip->Options[i].Emotes[j]._Emote;
347 }
348 }
349 }
350
351 SendPacket(&data);
352
353 LOG_DEBUG("network", "WORLD: Sent SMSG_NPC_TEXT_UPDATE");
354}
#define DEFAULT_LOCALE
Definition: Common.h:88
#define MAX_GOSSIP_TEXT_OPTIONS
Definition: NPCHandler.h:42
#define MAX_GOSSIP_TEXT_EMOTES
Definition: NPCHandler.h:30
@ GENDER_MALE
Definition: SharedDefines.h:60
@ GENDER_FEMALE
Definition: SharedDefines.h:61
@ SMSG_NPC_TEXT_UPDATE
Definition: Opcodes.h:414
std::string const & GetText(LocaleConstant locale=DEFAULT_LOCALE, uint8 gender=GENDER_MALE, bool forceGender=false) const
Definition: ObjectMgr.h:457
uint32 _Emote
Definition: NPCHandler.h:26
uint32 _Delay
Definition: NPCHandler.h:27
std::string Text_0
Definition: NPCHandler.h:34
QEmote Emotes[MAX_GOSSIP_TEXT_EMOTES]
Definition: NPCHandler.h:39
uint32 BroadcastTextID
Definition: NPCHandler.h:36
std::string Text_1
Definition: NPCHandler.h:35
GossipTextOption Options[MAX_GOSSIP_TEXT_OPTIONS]
Definition: NPCHandler.h:46

◆ HandleOfferPetitionOpcode()

void WorldSession::HandleOfferPetitionOpcode ( WorldPacket recvData)

Definition at line 549 of file PetitionsHandler.cpp.

550{
551 LOG_DEBUG("network", "Received opcode CMSG_OFFER_PETITION"); // ok
552
553 ObjectGuid petitionguid, plguid;
554 uint32 junk;
555 Player* player;
556 recvData >> junk; // this is not petition type!
557 recvData >> petitionguid; // petition guid
558 recvData >> plguid; // player guid
559
561 if (!player)
562 return;
563
564 Petition const* petition = sPetitionMgr->GetPetition(petitionguid);
565 if (!petition)
566 return;
567
568 if (GetPlayer()->GetTeamId() != player->GetTeamId())
569 {
570 if (petition->petitionType != GUILD_CHARTER_TYPE)
572 else
574 return;
575 }
576
577 if (petition->petitionType != GUILD_CHARTER_TYPE)
578 {
579 if (player->getLevel() < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
580 {
581 // player is too low level to join an arena team
583 return;
584 }
585
587 if (slot >= MAX_ARENA_SLOT)
588 return;
589
590 if (player->GetArenaTeamId(slot))
591 {
592 // player is already in an arena team
594 return;
595 }
596
597 if (player->GetArenaTeamIdInvited())
598 {
600 return;
601 }
602 }
603 else
604 {
605 if (player->GetGuildId())
606 {
608 return;
609 }
610
611 if (player->GetGuildIdInvited())
612 {
614 return;
615 }
616 }
617
618 Signatures const* signatures = sPetitionMgr->GetSignature(petitionguid);
619 uint8 signs = signatures ? signatures->signatureMap.size() : 0;
620
621 WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES, (8 + 8 + 4 + signs + signs * 12));
622 data << petitionguid; // petition guid
623 data << _player->GetGUID(); // owner guid
624 data << uint32(petitionguid.GetCounter()); // guild guid
625 data << uint8(signs); // sign's count
626
627 if (signs)
628 for (SignatureMap::const_iterator itr = signatures->signatureMap.begin(); itr != signatures->signatureMap.end(); ++itr)
629 {
630 data << itr->first; // Player GUID
631 data << uint32(0); // there 0 ...
632 }
633
634 player->GetSession()->SendPacket(&data);
635}
@ GUILD_COMMAND_INVITE
Definition: Guild.h:103
@ GUILD_COMMAND_CREATE
Definition: Guild.h:102
@ ERR_ALREADY_IN_GUILD_S
Definition: Guild.h:125
@ ERR_GUILD_NOT_ALLIED
Definition: Guild.h:135
@ ERR_ALREADY_INVITED_TO_GUILD_S
Definition: Guild.h:127
#define sPetitionMgr
Definition: PetitionMgr.h:88
@ SMSG_PETITION_SHOW_SIGNATURES
Definition: Opcodes.h:477
@ GUILD_CHARTER_TYPE
Definition: WorldSession.h:222
static uint8 GetSlotByType(uint32 type)
Definition: ArenaTeam.cpp:618
uint32 GetGuildIdInvited()
Definition: Player.h:1852
uint8 petitionType
Definition: PetitionMgr.h:43
SignatureMap signatureMap
Definition: PetitionMgr.h:50

◆ HandleOpenItemOpcode()

void WorldSession::HandleOpenItemOpcode ( WorldPacket recvPacket)

Definition at line 169 of file SpellHandler.cpp.

170{
171 LOG_DEBUG("network", "WORLD: CMSG_OPEN_ITEM packet, data length = {}", (uint32)recvPacket.size());
172
173 Player* pUser = _player;
174
175 // ignore for remote control state
176 if (pUser->m_mover != pUser)
177 return;
178
179 // xinef: additional check, client outputs message on its own
180 if (!pUser->IsAlive())
181 {
182 pUser->SendEquipError(EQUIP_ERR_YOU_ARE_DEAD, nullptr, nullptr);
183 return;
184 }
185
186 uint8 bagIndex, slot;
187
188 recvPacket >> bagIndex >> slot;
189
190 LOG_DEBUG("network.opcode", "bagIndex: {}, slot: {}", bagIndex, slot);
191
192 Item* item = pUser->GetItemByPos(bagIndex, slot);
193 if (!item)
194 {
195 pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
196 return;
197 }
198
199 ItemTemplate const* proto = item->GetTemplate();
200 if (!proto)
201 {
202 pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, item, nullptr);
203 return;
204 }
205
206 // Verify that the bag is an actual bag or wrapped item that can be used "normally"
208 {
209 pUser->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW, item, nullptr);
210 LOG_ERROR("network.opcode", "Possible hacking attempt: Player {} [{}] tried to open item [{}, entry: {}] which is not openable!",
211 pUser->GetName(), pUser->GetGUID().ToString(), item->GetGUID().ToString(), proto->ItemId);
212 return;
213 }
214
215 // locked item
216 uint32 lockId = proto->LockID;
217 if (lockId)
218 {
219 LockEntry const* lockInfo = sLockStore.LookupEntry(lockId);
220
221 if (!lockInfo)
222 {
223 pUser->SendEquipError(EQUIP_ERR_ITEM_LOCKED, item, nullptr);
224 LOG_ERROR("network.opcode", "WORLD::OpenItem: item [{}] has an unknown lockId: {}!", item->GetGUID().ToString(), lockId);
225 return;
226 }
227
228 // was not unlocked yet
229 if (item->IsLocked())
230 {
231 pUser->SendEquipError(EQUIP_ERR_ITEM_LOCKED, item, nullptr);
232 return;
233 }
234 }
235
236 if (sScriptMgr->OnBeforeOpenItem(pUser, item))
237 {
238 if (item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_WRAPPED))// wrapped?
239 {
241 stmt->SetData(0, item->GetGUID().GetCounter());
243 .WithPreparedCallback(std::bind(&WorldSession::HandleOpenWrappedItemCallback, this, bagIndex, slot, item->GetGUID().GetCounter(), std::placeholders::_1)));
244 }
245 else
246 {
247 pUser->SendLoot(item->GetGUID(), LOOT_CORPSE);
248 }
249 }
250}
@ CHAR_SEL_CHARACTER_GIFT_BY_ITEM
DBCStorage< LockEntry > sLockStore(LockEntryfmt)
@ EQUIP_ERR_ITEM_LOCKED
Definition: Item.h:77
@ EQUIP_ERR_YOU_ARE_DEAD
Definition: Item.h:79
@ EQUIP_ERR_CANT_DO_RIGHT_NOW
Definition: Item.h:80
@ ITEM_FIELD_FLAG_WRAPPED
Definition: ItemTemplate.h:113
bool IsLocked() const
Definition: Item.h:247
bool HasFlag(uint16 index, uint32 flag) const
Definition: Object.cpp:889
void HandleOpenWrappedItemCallback(uint8 bagIndex, uint8 slot, ObjectGuid::LowType itemLowGUID, PreparedQueryResult result)

◆ HandleOpenWrappedItemCallback()

void WorldSession::HandleOpenWrappedItemCallback ( uint8  bagIndex,
uint8  slot,
ObjectGuid::LowType  itemLowGUID,
PreparedQueryResult  result 
)

Definition at line 252 of file SpellHandler.cpp.

253{
254 if (!GetPlayer())
255 return;
256
257 Item* item = GetPlayer()->GetItemByPos(bagIndex, slot);
258 if (!item)
259 return;
260
261 if (item->GetGUID().GetCounter() != itemLowGUID || !item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_WRAPPED)) // during getting result, gift was swapped with another item
262 return;
263
264 if (!result)
265 {
266 LOG_ERROR("network", "Wrapped item {} don't have record in character_gifts table and will deleted", item->GetGUID().ToString());
267 GetPlayer()->DestroyItem(item->GetBagSlot(), item->GetSlot(), true);
268 return;
269 }
270
271 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
272
273 Field* fields = result->Fetch();
274 uint32 entry = fields[0].Get<uint32>();
275 uint32 flags = fields[1].Get<uint32>();
276
278 item->SetEntry(entry);
279 item->SetUInt32Value(ITEM_FIELD_FLAGS, flags);
281
284
286 stmt->SetData(0, item->GetGUID().GetCounter());
287 trans->Append(stmt);
288
289 CharacterDatabase.CommitTransaction(trans);
290}
@ CHAR_DEL_GIFT
void SetEntry(uint32 entry)
Definition: Object.h:110

◆ HandleOptOutOfLootOpcode()

void WorldSession::HandleOptOutOfLootOpcode ( WorldPacket recvData)

Definition at line 1118 of file GroupHandler.cpp.

1119{
1120 LOG_DEBUG("network", "WORLD: Received CMSG_OPT_OUT_OF_LOOT");
1121
1122 uint32 passOnLoot;
1123 recvData >> passOnLoot; // 1 always pass, 0 do not pass
1124
1125 if (!GetPlayer())
1126 return;
1127
1128 GetPlayer()->SetPassOnGroupLoot(passOnLoot);
1129}
void SetPassOnGroupLoot(bool bPassOnGroupLoot)
Definition: Player.h:2437

◆ HandlePageTextQueryOpcode()

void WorldSession::HandlePageTextQueryOpcode ( WorldPacket recvPacket)

Only static data is sent in this packet !!!

Definition at line 357 of file QueryHandler.cpp.

358{
359 LOG_DEBUG("network", "WORLD: Received CMSG_PAGE_TEXT_QUERY");
360
361 uint32 pageID;
362 recvData >> pageID;
363 recvData.read_skip<uint64>(); // guid
364
365 while (pageID)
366 {
367 PageText const* pageText = sObjectMgr->GetPageText(pageID);
368 // guess size
370 data << pageID;
371
372 if (!pageText)
373 {
374 data << "Item page missing.";
375 data << uint32(0);
376 pageID = 0;
377 }
378 else
379 {
380 std::string Text = pageText->Text;
381
382 int loc_idx = GetSessionDbLocaleIndex();
383 if (loc_idx >= 0)
384 if (PageTextLocale const* player = sObjectMgr->GetPageTextLocale(pageID))
385 ObjectMgr::GetLocaleString(player->Text, loc_idx, Text);
386
387 data << Text;
388 data << uint32(pageText->NextPage);
389 pageID = pageText->NextPage;
390 }
391 SendPacket(&data);
392
393 LOG_DEBUG("network", "WORLD: Sent SMSG_PAGE_TEXT_QUERY_RESPONSE");
394 }
395}
@ SMSG_PAGE_TEXT_QUERY_RESPONSE
Definition: Opcodes.h:121
uint16 NextPage
Definition: ObjectMgr.h:62
std::string Text
Definition: ObjectMgr.h:61

◆ HandlePartyAssignmentOpcode()

void WorldSession::HandlePartyAssignmentOpcode ( WorldPacket recvData)

Definition at line 699 of file GroupHandler.cpp.

700{
701 LOG_DEBUG("network", "WORLD: Received MSG_PARTY_ASSIGNMENT");
702
703 Group* group = GetPlayer()->GetGroup();
704 if (!group)
705 return;
706
707 ObjectGuid senderGuid = GetPlayer()->GetGUID();
708 if (!group->IsLeader(senderGuid) && !group->IsAssistant(senderGuid))
709 return;
710
711 uint8 assignment;
712 bool apply;
713 ObjectGuid guid;
714 recvData >> assignment >> apply;
715 recvData >> guid;
716
717 switch (assignment)
718 {
721 group->SetGroupMemberFlag(guid, apply, MEMBER_FLAG_MAINASSIST);
722 break;
724 group->RemoveUniqueGroupMemberFlag(MEMBER_FLAG_MAINTANK); // Remove main assist flag from current if any.
725 group->SetGroupMemberFlag(guid, apply, MEMBER_FLAG_MAINTANK);
726 default:
727 break;
728 }
729
730 group->SendUpdate();
731}
@ GROUP_ASSIGN_MAINASSIST
Definition: Group.h:80
@ GROUP_ASSIGN_MAINTANK
Definition: Group.h:79
@ MEMBER_FLAG_MAINASSIST
Definition: Group.h:74
@ MEMBER_FLAG_MAINTANK
Definition: Group.h:73
void RemoveUniqueGroupMemberFlag(GroupMemberFlags flag)
Definition: Group.cpp:2452

◆ HandlePetAbandon()

void WorldSession::HandlePetAbandon ( WorldPackets::Pet::PetAbandon packet)

Definition at line 921 of file PetHandler.cpp.

922{
923 if (!_player->IsInWorld())
924 return;
925
926 // pet/charmed
928 if (pet && pet->ToPet() && pet->ToPet()->getPetType() == HUNTER_PET)
929 {
930 if (pet->IsPet())
931 {
932 if (pet->GetGUID() == _player->GetPetGUID())
933 {
934 uint32 feelty = pet->GetPower(POWER_HAPPINESS);
935 pet->SetPower(POWER_HAPPINESS, feelty > 50000 ? (feelty - 50000) : 0);
936 }
937
939 }
940 else if (pet->GetGUID() == _player->GetCharmGUID())
942 }
943}
@ PET_SAVE_AS_DELETED
Definition: PetDefines.h:41
@ HUNTER_PET
Definition: PetDefines.h:32
@ POWER_HAPPINESS
PetType getPetType() const
Definition: Pet.h:50
void StopCastingCharm()
Definition: Player.cpp:9166
void RemovePet(Pet *pet, PetSaveMode mode, bool returnreagent=false)
Definition: Player.cpp:8915
Pet * ToPet()
Definition: Unit.h:2393
bool IsPet() const
Definition: Unit.h:1413
void SetPower(Powers power, uint32 val, bool withPowerUpdate=true)
Definition: Unit.cpp:15423
ObjectGuid GetPetGUID() const
Definition: Unit.h:1821

◆ HandlePetAction()

void WorldSession::HandlePetAction ( WorldPacket recvData)

Definition at line 57 of file PetHandler.cpp.

58{
59 ObjectGuid guid1;
60 uint32 data;
61 ObjectGuid guid2;
62 recvData >> guid1; //pet guid
63 recvData >> data;
64 recvData >> guid2; //tag guid
65
66 uint32 spellId = UNIT_ACTION_BUTTON_ACTION(data);
67 uint8 flag = UNIT_ACTION_BUTTON_TYPE(data); //delete = 0x07 CastSpell = C1
68
69 // used also for charmed creature
70 Unit* pet = ObjectAccessor::GetUnit(*_player, guid1);
71 LOG_DEBUG("network.opcode", "HandlePetAction: Pet {} - flag: {}, spellId: {}, target: {}.", guid1.ToString(), uint32(flag), spellId, guid2.ToString());
72
73 if (!pet)
74 {
75 LOG_ERROR("network.opcode", "HandlePetAction: Pet ({}) doesn't exist for player {}", guid1.ToString(), GetPlayer()->GetName());
76 return;
77 }
78
79 if (pet != GetPlayer()->GetFirstControlled())
80 {
81 LOG_ERROR("network.opcode", "HandlePetAction: Pet ({}) does not belong to player {}", guid1.ToString(), GetPlayer()->GetName());
82 return;
83 }
84
85 if (!pet->IsAlive())
86 {
87 // xinef: allow dissmis dead pets
88 SpellInfo const* spell = (flag == ACT_ENABLED || flag == ACT_PASSIVE) ? sSpellMgr->GetSpellInfo(spellId) : nullptr;
89 if ((flag != ACT_COMMAND || spellId != COMMAND_ABANDON) && (!spell || !spell->HasAttribute(SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD)))
90 return;
91 }
92
93 // Xinef: allow to controll players
94 if (pet->GetTypeId() == TYPEID_PLAYER && flag != ACT_COMMAND && flag != ACT_REACTION)
95 return;
96
97 // Do not follow itself vehicle
98 if (spellId == COMMAND_FOLLOW && _player->IsOnVehicle(pet))
99 {
100 return;
101 }
102
103 if (GetPlayer()->m_Controlled.size() == 1)
104 HandlePetActionHelper(pet, guid1, spellId, flag, guid2);
105 else
106 {
107 //If a pet is dismissed, m_Controlled will change
108 std::vector<Unit*> controlled;
109 for (Unit::ControlSet::iterator itr = GetPlayer()->m_Controlled.begin(); itr != GetPlayer()->m_Controlled.end(); ++itr)
110 {
111 // xinef: allow to dissmis dead pets
112 if ((*itr)->GetEntry() == pet->GetEntry() && ((*itr)->IsAlive() || (flag == ACT_COMMAND && spellId == COMMAND_ABANDON)))
113 controlled.push_back(*itr);
114 // xinef: mirror image blizzard crappness
115 else if ((*itr)->GetEntry() == NPC_MIRROR_IMAGE && flag == ACT_COMMAND && spellId == COMMAND_FOLLOW)
116 {
117 (*itr)->InterruptNonMeleeSpells(false);
118 }
119 }
120
121 for (Unit* pet : controlled)
122 if (pet && pet->IsInWorld() && pet->GetMap() == _player->GetMap())
123 HandlePetActionHelper(pet, guid1, spellId, flag, guid2);
124 }
125}
@ NPC_MIRROR_IMAGE
Definition: PetDefines.h:105
#define UNIT_ACTION_BUTTON_ACTION(X)
Definition: Unit.h:1036
@ COMMAND_ABANDON
Definition: Unit.h:1033
@ COMMAND_FOLLOW
Definition: Unit.h:1031
@ ACT_REACTION
Definition: Unit.h:1017
@ ACT_COMMAND
Definition: Unit.h:1016
@ ACT_ENABLED
Definition: Unit.h:1015
@ ACT_PASSIVE
Definition: Unit.h:1013
#define UNIT_ACTION_BUTTON_TYPE(X)
Definition: Unit.h:1037
@ SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD
ControlSet m_Controlled
Definition: Unit.h:1864
void HandlePetActionHelper(Unit *pet, ObjectGuid guid1, uint32 spellid, uint16 flag, ObjectGuid guid2)
Definition: PetHandler.cpp:150

◆ HandlePetActionHelper()

void WorldSession::HandlePetActionHelper ( Unit pet,
ObjectGuid  guid1,
uint32  spellid,
uint16  flag,
ObjectGuid  guid2 
)

Definition at line 150 of file PetHandler.cpp.

151{
152 CharmInfo* charmInfo = pet->GetCharmInfo();
153 if (!charmInfo)
154 {
155 LOG_ERROR("network.opcode", "WorldSession::HandlePetAction(petGuid: {}, tagGuid: {}, spellId: {}, flag: {}): object ({}) is considered pet-like but doesn't have a charminfo!",
156 guid1.ToString(), guid2.ToString(), spellId, flag, pet->GetGUID().ToString());
157 return;
158 }
159
160 switch (flag)
161 {
162 case ACT_COMMAND: //0x07
163 switch (spellId)
164 {
165 case COMMAND_STAY: //flat=1792 //STAY
166 {
168 if (!controlledMotion)
169 {
171 pet->GetMotionMaster()->Clear(false);
172 pet->GetMotionMaster()->MoveIdle();
173 }
174
175 charmInfo->SetCommandState(COMMAND_STAY);
176 charmInfo->SetIsCommandAttack(false);
177 charmInfo->SetIsCommandFollow(false);
178 charmInfo->SetIsFollowing(false);
179 charmInfo->SetIsReturning(false);
180 charmInfo->SetIsAtStay(!controlledMotion);
181 charmInfo->SaveStayPosition(controlledMotion);
182 if (pet->ToPet())
184
185 charmInfo->SetForcedSpell(0);
186 charmInfo->SetForcedTargetGUID();
187 break;
188 }
189 case COMMAND_FOLLOW: //spellId=1792 //FOLLOW
190 {
191 pet->AttackStop();
192 pet->InterruptNonMeleeSpells(false);
193 pet->ClearInPetCombat();
195 if (pet->ToPet())
198
199 charmInfo->SetIsCommandAttack(false);
200 charmInfo->SetIsAtStay(false);
201 charmInfo->SetIsReturning(true);
202 charmInfo->SetIsCommandFollow(true);
203 charmInfo->SetIsFollowing(false);
204 charmInfo->RemoveStayPosition();
205 charmInfo->SetForcedSpell(0);
206 charmInfo->SetForcedTargetGUID();
207 break;
208 }
209 case COMMAND_ATTACK: //spellId=1792 //ATTACK
210 {
211 // Can't attack if owner is pacified
213 {
214 //pet->SendPetCastFail(spellId, SPELL_FAILED_PACIFIED);
215 //TODO: Send proper error message to client
216 return;
217 }
218
219 // only place where pet can be player
220 Unit* TargetUnit = ObjectAccessor::GetUnit(*_player, guid2);
221 if (!TargetUnit)
222 return;
223
224 if (Unit* owner = pet->GetOwner())
225 if (!owner->IsValidAttackTarget(TargetUnit))
226 return;
227
228 // pussywizard (excluded charmed)
229 if (!pet->IsCharmed())
230 if (Creature* creaturePet = pet->ToCreature())
231 if (!creaturePet->CanCreatureAttack(TargetUnit))
232 return;
233
234 // Not let attack through obstructions
235 bool checkLos = !DisableMgr::IsPathfindingEnabled(pet->GetMap()) ||
236 (TargetUnit->GetTypeId() == TYPEID_UNIT && (TargetUnit->ToCreature()->isWorldBoss() || TargetUnit->ToCreature()->IsDungeonBoss()));
237
238 if (checkLos && !pet->IsWithinLOSInMap(TargetUnit))
239 {
240 WorldPacket data(SMSG_CAST_FAILED, 1 + 4 + 1);
241 data << uint8(0);
242 data << uint32(7389);
244 SendPacket(&data);
245 return;
246 }
247
249 // This is true if pet has no target or has target but targets differs.
250 if (pet->GetVictim() != TargetUnit || (pet->GetVictim() == TargetUnit && !pet->GetCharmInfo()->IsCommandAttack()))
251 {
252 pet->AttackStop();
253
254 if (pet->GetTypeId() != TYPEID_PLAYER && pet->ToCreature()->IsAIEnabled)
255 {
256 charmInfo->SetIsCommandAttack(true);
257 charmInfo->SetIsAtStay(false);
258 charmInfo->SetIsFollowing(false);
259 charmInfo->SetIsCommandFollow(false);
260 charmInfo->SetIsReturning(false);
261
262 pet->ToCreature()->AI()->AttackStart(TargetUnit);
263
264 //10% chance to play special pet attack talk, else growl
265 if (pet->IsPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && pet != TargetUnit && urand(0, 100) < 10)
267 else
268 {
269 // 90% chance for pet and 100% chance for charmed creature
270 pet->SendPetAIReaction(guid1);
271 }
272 }
273 else // charmed player
274 {
275 charmInfo->SetIsCommandAttack(true);
276 charmInfo->SetIsAtStay(false);
277 charmInfo->SetIsFollowing(false);
278 charmInfo->SetIsCommandFollow(false);
279 charmInfo->SetIsReturning(false);
280
281 pet->Attack(TargetUnit, true);
282 pet->SendPetAIReaction(guid1);
283 }
284 }
285 break;
286 }
287 case COMMAND_ABANDON: // abandon (hunter pet) or dismiss (summoned pet)
288 if (pet->GetCharmerGUID() == GetPlayer()->GetGUID())
289 {
290 if (pet->IsSummon())
291 pet->ToTempSummon()->UnSummon();
292 else
294 }
295 else if (pet->GetOwnerGUID() == GetPlayer()->GetGUID())
296 {
297 ASSERT(pet->GetTypeId() == TYPEID_UNIT);
298 if (pet->IsPet())
299 {
300 if (pet->ToPet()->getPetType() == HUNTER_PET)
302 else
303 //dismissing a summoned pet is like killing them (this prevents returning a soulshard...)
304 pet->setDeathState(CORPSE);
305 }
307 {
308 pet->ToTempSummon()->UnSummon();
309 }
310 }
311 break;
312 default:
313 LOG_ERROR("network.opcode", "WORLD: unknown PET flag Action {} and spellId {}.", uint32(flag), spellId);
314 }
315 break;
316 case ACT_REACTION: // 0x6
317 switch (spellId)
318 {
319 case REACT_PASSIVE: //passive
320 pet->AttackStop();
321 if (pet->ToPet())
323 pet->ClearInPetCombat();
324 [[fallthrough]]; // TODO: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked.
325
326 case REACT_DEFENSIVE: //recovery
327 case REACT_AGGRESSIVE: //activete
328 if (pet->GetTypeId() == TYPEID_UNIT)
329 pet->ToCreature()->SetReactState(ReactStates(spellId));
330 else
331 charmInfo->SetPlayerReactState(ReactStates(spellId));
332 break;
333 }
334 break;
335 case ACT_DISABLED: // 0x81 spell (disabled), ignore
336 case ACT_PASSIVE: // 0x01
337 case ACT_ENABLED: // 0xC1 spell
338 {
339 Unit* unit_target = nullptr;
340
341 // do not cast unknown spells
342 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
343 if (!spellInfo)
344 {
345 LOG_ERROR("network.opcode", "WORLD: unknown PET spell id {}", spellId);
346 return;
347 }
348
349 if (guid2)
350 unit_target = ObjectAccessor::GetUnit(*_player, guid2);
351 else if (!spellInfo->IsPositive())
352 return;
353
354 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
355 {
356 if (spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_SRC_AREA_ENEMY || spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_DEST_AREA_ENEMY || spellInfo->Effects[i].TargetA.GetTarget() == TARGET_DEST_DYNOBJ_ENEMY)
357 return;
358 }
359
360 // Clear the flags as if owner clicked 'attack'. AI will reset them
361 // after AttackStart, even if spell failed
362 charmInfo->SetIsAtStay(false);
363 charmInfo->SetIsCommandAttack(true);
364 charmInfo->SetIsReturning(false);
365 charmInfo->SetIsFollowing(false);
366
367 TriggerCastFlags triggerCastFlags = TRIGGERED_NONE;
368
369 if (spellInfo->IsPassive())
370 return;
371
372 // cast only learned spells
373 if (!pet->HasSpell(spellId))
374 {
375 bool allow = false;
376
377 // allow casting of spells triggered by clientside periodic trigger auras
379 {
380 allow = true;
381 triggerCastFlags = TRIGGERED_FULL_MASK;
382 }
383
384 if (!allow)
385 return;
386 }
387
388 Spell* spell = new Spell(pet, spellInfo, triggerCastFlags);
389 spell->LoadScripts(); // xinef: load for CheckPetCast
390
391 SpellCastResult result = spell->CheckPetCast(unit_target);
392
393 //auto turn to target unless possessed
394 if (result == SPELL_FAILED_UNIT_NOT_INFRONT && !pet->isPossessed() && !pet->IsVehicle())
395 {
396 if (unit_target)
397 {
398 pet->SetInFront(unit_target);
399 if (unit_target->GetTypeId() == TYPEID_PLAYER)
400 pet->SendUpdateToPlayer(unit_target->ToPlayer());
401 }
402 else if (Unit* unit_target2 = spell->m_targets.GetUnitTarget())
403 {
404 pet->SetInFront(unit_target2);
405 if (unit_target2->GetTypeId() == TYPEID_PLAYER)
406 pet->SendUpdateToPlayer(unit_target2->ToPlayer());
407 }
408 if (Unit* powner = pet->GetCharmerOrOwner())
409 if (powner->GetTypeId() == TYPEID_PLAYER)
410 pet->SendUpdateToPlayer(powner->ToPlayer());
411
412 result = SPELL_CAST_OK;
413 }
414
415 if (result == SPELL_CAST_OK)
416 {
417 if (!spellInfo->IsCooldownStartedOnEvent())
418 {
419 pet->ToCreature()->AddSpellCooldown(spellId, 0, 0);
420 }
421
422 unit_target = spell->m_targets.GetUnitTarget();
423
424 //10% chance to play special pet attack talk, else growl
425 //actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell
426 if (pet->IsPet() && (((Pet*)pet)->getPetType() == SUMMON_PET) && (pet != unit_target) && (urand(0, 100) < 10))
428 else
429 {
430 pet->SendPetAIReaction(guid1);
431 }
432
433 if (unit_target && !GetPlayer()->IsFriendlyTo(unit_target) && !pet->isPossessed() && !pet->IsVehicle())
434 {
435 // This is true if pet has no target or has target but targets differs.
436 if (pet->GetVictim() != unit_target)
437 {
438 if (pet->ToCreature()->IsAIEnabled)
439 pet->ToCreature()->AI()->AttackStart(unit_target);
440 }
441 }
442
443 spell->prepare(&(spell->m_targets));
444
445 charmInfo->SetForcedSpell(0);
446 charmInfo->SetForcedTargetGUID();
447 }
448 else if (pet->ToPet() && (result == SPELL_FAILED_LINE_OF_SIGHT || result == SPELL_FAILED_OUT_OF_RANGE))
449 {
450 unit_target = spell->m_targets.GetUnitTarget();
451 bool haspositiveeffect = false;
452
453 if (!unit_target)
454 return;
455
456 // search positive effects for spell
457 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
458 {
459 if (spellInfo->_IsPositiveEffect(i, true))
460 {
461 haspositiveeffect = true;
462 break;
463 }
464 }
465
466 if (pet->isPossessed() || pet->IsVehicle())
467 Spell::SendCastResult(GetPlayer(), spellInfo, 0, result);
468 else if (GetPlayer()->IsFriendlyTo(unit_target) && !haspositiveeffect)
470 else
472
473 if (!pet->HasSpellCooldown(spellId))
474 if(pet->ToPet())
475 pet->ToPet()->RemoveSpellCooldown(spellId, true);
476
477 spell->finish(false);
478 delete spell;
479
481 return;
482
483 bool tempspellIsPositive = false;
484
485 if (!GetPlayer()->IsFriendlyTo(unit_target))
486 {
487 // only place where pet can be player
488 Unit* TargetUnit = ObjectAccessor::GetUnit(*_player, guid2);
489 if (!TargetUnit)
490 return;
491
492 if (Unit* owner = pet->GetOwner())
493 if (!owner->IsValidAttackTarget(TargetUnit))
494 return;
495
497 // This is true if pet has no target or has target but targets differs.
498 if (pet->GetVictim() != TargetUnit || (pet->GetVictim() == TargetUnit && !pet->GetCharmInfo()->IsCommandAttack()))
499 {
500 if (pet->GetVictim())
501 pet->AttackStop();
502
503 if (pet->GetTypeId() != TYPEID_PLAYER && pet->ToCreature() && pet->ToCreature()->IsAIEnabled)
504 {
505 charmInfo->SetIsCommandAttack(true);
506 charmInfo->SetIsAtStay(false);
507 charmInfo->SetIsFollowing(false);
508 charmInfo->SetIsCommandFollow(false);
509 charmInfo->SetIsReturning(false);
510
511 pet->ToCreature()->AI()->AttackStart(TargetUnit);
512
513 if (pet->IsPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && pet != TargetUnit && urand(0, 100) < 10)
515 else
516 pet->SendPetAIReaction(guid1);
517 }
518 else // charmed player
519 {
520 if (pet->GetVictim() && pet->GetVictim() != TargetUnit)
521 pet->AttackStop();
522
523 charmInfo->SetIsCommandAttack(true);
524 charmInfo->SetIsAtStay(false);
525 charmInfo->SetIsFollowing(false);
526 charmInfo->SetIsCommandFollow(false);
527 charmInfo->SetIsReturning(false);
528
529 pet->Attack(TargetUnit, true);
530 pet->SendPetAIReaction(guid1);
531 }
532
533 pet->ToPet()->CastWhenWillAvailable(spellId, unit_target, nullptr, tempspellIsPositive);
534 }
535 }
536 else if (haspositiveeffect)
537 {
538 bool tmpSpellIsPositive = true;
540 // This is true if pet has no target or has target but targets differs.
541 Unit* victim = pet->GetVictim();
542 if (victim)
543 {
544 pet->AttackStop();
545 }
546 else
547 victim = nullptr;
548
549 if (pet->GetTypeId() != TYPEID_PLAYER && pet->ToCreature() && pet->ToCreature()->IsAIEnabled)
550 {
551 pet->StopMoving();
552 pet->GetMotionMaster()->Clear();
553
554 charmInfo->SetIsCommandAttack(false);
555 charmInfo->SetIsAtStay(false);
556 charmInfo->SetIsFollowing(false);
557 charmInfo->SetIsCommandFollow(false);
558 charmInfo->SetIsReturning(false);
559
560 pet->GetMotionMaster()->MoveFollow(unit_target, PET_FOLLOW_DIST, rand_norm() * 2 * M_PI);
561
562 if (pet->IsPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && pet != unit_target && urand(0, 100) < 10)
564 else
565 {
566 pet->SendPetAIReaction(guid1);
567 }
568
569 pet->ToPet()->CastWhenWillAvailable(spellId, unit_target, victim, tmpSpellIsPositive);
570 }
571 }
572 }
573 else
574 {
575 // dont spam alerts
576 if (!charmInfo->GetForcedSpell())
577 {
578 if (pet->isPossessed() || pet->IsVehicle())
579 Spell::SendCastResult(GetPlayer(), spellInfo, 0, result);
580 else
581 spell->SendPetCastResult(result);
582 }
583
584 if (!pet->ToCreature()->HasSpellCooldown(spellId))
585 GetPlayer()->SendClearCooldown(spellId, pet);
586
587 spell->finish(false);
588 delete spell;
589
590 // reset specific flags in case of spell fail. AI will reset other flags
591 pet->PetSpellFail(spellInfo, unit_target, result);
592 }
593 break;
594 }
595 default:
596 LOG_ERROR("network.opcode", "WORLD: unknown PET flag Action {} and spellId {}.", uint32(flag), spellId);
597 }
598}
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:44
double rand_norm()
Definition: Random.cpp:77
#define PET_FOLLOW_DIST
Definition: PetDefines.h:193
@ SUMMON_PET
Definition: PetDefines.h:31
@ PET_TALK_SPECIAL_SPELL
Definition: PetDefines.h:80
@ PET_TALK_ATTACK
Definition: PetDefines.h:81
@ UNIT_MASK_CONTROLABLE_GUARDIAN
Definition: Unit.h:683
@ UNIT_MASK_SUMMON
Definition: Unit.h:675
@ UNIT_MASK_GUARDIAN
Definition: Unit.h:677
@ UNIT_MASK_MINION
Definition: Unit.h:676
ReactStates
Definition: Unit.h:1022
@ REACT_DEFENSIVE
Definition: Unit.h:1024
@ REACT_PASSIVE
Definition: Unit.h:1023
@ REACT_AGGRESSIVE
Definition: Unit.h:1025
@ CORPSE
Definition: Unit.h:318
@ COMMAND_ATTACK
Definition: Unit.h:1032
@ COMMAND_STAY
Definition: Unit.h:1030
@ ACT_DISABLED
Definition: Unit.h:1014
@ UNIT_STATE_FOLLOW
Definition: Unit.h:334
@ MOTION_SLOT_CONTROLLED
Definition: MotionMaster.h:63
@ NULL_MOTION_TYPE
Definition: MotionMaster.h:56
@ SPELL_AURA_MOD_PACIFY
@ SPELL_AURA_PERIODIC_TRIGGER_SPELL_FROM_CLIENT
#define MAX_SPELL_EFFECTS
@ TARGET_DEST_DYNOBJ_ENEMY
@ TARGET_UNIT_DEST_AREA_ENEMY
@ TARGET_UNIT_SRC_AREA_ENEMY
@ SPELL_FAILED_UNIT_NOT_INFRONT
@ SPELL_FAILED_OUT_OF_RANGE
@ SPELL_FAILED_DONT_REPORT
@ SPELL_FAILED_LINE_OF_SIGHT
@ SPELL_FAILED_TARGET_FRIENDLY
@ SMSG_CAST_FAILED
Definition: Opcodes.h:334
bool IsPathfindingEnabled(const Map *map)
Definition: DisableMgr.cpp:402
virtual void AttackStart(Unit *)
Definition: UnitAI.cpp:28
bool IsDungeonBoss() const
Definition: Creature.cpp:3035
bool isWorldBoss() const
Definition: Creature.h:114
bool HasSpellCooldown(uint32 spell_id) const override
Definition: Creature.cpp:2791
void SetReactState(ReactStates st)
Definition: Creature.h:88
void AddSpellCooldown(uint32 spell_id, uint32, uint32 end_time, bool needSendToClient=false, bool forceSendToSpectator=false) override
Definition: Creature.cpp:2746
bool IsWithinLOSInMap(WorldObject const *obj, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS, Optional< float > collisionHeight={ }) const
Definition: Object.cpp:1347
void ClearCastWhenWillAvailable()
Definition: Pet.cpp:2395
Player * GetOwner() const
Definition: Pet.cpp:2438
void setDeathState(DeathState s, bool despawn=false) override
Definition: Pet.cpp:618
void CastWhenWillAvailable(uint32 spellid, Unit *spellTarget, Unit *oldTarget, bool spellIsPositive=false)
Definition: Pet.cpp:2379
void RemoveSpellCooldown(uint32 spell_id, bool update)
Definition: Pet.cpp:2403
bool HasSpell(uint32 spell) const override
Definition: Pet.cpp:2285
void SendClearCooldown(uint32 spell_id, Unit *target)
Definition: Player.cpp:14343
void RemoveStayPosition()
Definition: Unit.cpp:20384
int32 GetForcedSpell()
Definition: Unit.h:1145
void SetIsCommandFollow(bool val)
Definition: Unit.cpp:20344
bool IsCommandAttack()
Definition: Unit.cpp:20339
void SetIsAtStay(bool val)
Definition: Unit.cpp:20396
void SetIsFollowing(bool val)
Definition: Unit.cpp:20406
void SetIsReturning(bool val)
Definition: Unit.cpp:20416
void SaveStayPosition(bool atCurrentPos)
Definition: Unit.cpp:20354
void SetForcedSpell(uint32 id)
Definition: Unit.h:1144
void SetPlayerReactState(ReactStates s)
Definition: Unit.h:1150
void SetForcedTargetGUID(ObjectGuid guid=ObjectGuid::Empty)
Definition: Unit.h:1146
void SetCommandState(CommandStates st)
Definition: Unit.h:1102
void SetIsCommandAttack(bool val)
Definition: Unit.cpp:20334
void ClearUnitState(uint32 f)
Definition: Unit.h:1399
bool IsVehicle() const
Definition: Unit.h:1416
Unit * GetOwner() const
Definition: Unit.cpp:10548
void PetSpellFail(SpellInfo const *spellInfo, Unit *target, uint32 result)
Definition: Unit.cpp:20426
void StopMoving()
Definition: Unit.cpp:16736
CharmInfo * GetCharmInfo()
Definition: Unit.h:1880
Unit * GetCharmerOrOwner() const
Definition: Unit.h:1844
void ClearInPetCombat()
Definition: Unit.cpp:13737
bool isPossessed() const
Definition: Unit.h:1869
void SendPetTalk(uint32 pettalk)
Definition: Unit.cpp:16705
void SendPetAIReaction(ObjectGuid guid)
Definition: Unit.cpp:16717
virtual float GetFollowAngle() const
Definition: Unit.h:2387
Unit * GetVictim() const
Definition: Unit.h:1386
void StopMovingOnCurrentPos()
Definition: Unit.cpp:16775
bool IsAIEnabled
Definition: Unit.h:2345
ObjectGuid GetOwnerGUID() const
Definition: Unit.h:1811
uint32 HasUnitTypeMask(uint32 mask) const
Definition: Unit.h:1407
ObjectGuid GetCharmerGUID() const
Definition: Unit.h:1817
bool HasAuraTypeWithTriggerSpell(AuraType auratype, uint32 triggerSpell) const
Definition: Unit.cpp:5656
void SetInFront(WorldObject const *target)
Definition: Unit.cpp:20613
MovementGeneratorType GetMotionSlotType(int slot) const
void MoveFollow(Unit *target, float dist, float angle, MovementSlot slot=MOTION_SLOT_ACTIVE)
void Clear(bool reset=true)
Definition: MotionMaster.h:165
void LoadScripts()
Definition: Spell.cpp:8444
void SendPetCastResult(SpellCastResult result)
Definition: Spell.cpp:4648
SpellCastResult CheckPetCast(Unit *target)
Definition: Spell.cpp:6771
void finish(bool ok=true)
Definition: Spell.cpp:4437
bool IsCooldownStartedOnEvent() const
Definition: SpellInfo.cpp:1195
bool _IsPositiveEffect(uint8 effIndex, bool deep) const
Definition: SpellInfo.cpp:2600

◆ HandlePetCancelAuraOpcode()

void WorldSession::HandlePetCancelAuraOpcode ( WorldPacket recvPacket)

Definition at line 524 of file SpellHandler.cpp.

525{
526 ObjectGuid guid;
527 uint32 spellId;
528
529 recvPacket >> guid;
530 recvPacket >> spellId;
531
532 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
533 if (!spellInfo)
534 {
535 LOG_ERROR("network.opcode", "WORLD: unknown PET spell id {}", spellId);
536 return;
537 }
538
540
541 if (!pet)
542 {
543 LOG_ERROR("network.opcode", "HandlePetCancelAura: Attempt to cancel an aura for non-existant pet {} by player {}", guid.ToString(), GetPlayer()->GetName());
544 return;
545 }
546
547 if (pet != GetPlayer()->GetGuardianPet() && pet != GetPlayer()->GetCharm())
548 {
549 LOG_ERROR("network.opcode", "HandlePetCancelAura: Pet {} is not a pet of player {}", guid.ToString(), GetPlayer()->GetName());
550 return;
551 }
552
553 if (!pet->IsAlive())
554 {
556 return;
557 }
558
560}
@ FEEDBACK_PET_DEAD
Definition: PetDefines.h:73
void SendPetActionFeedback(uint8 msg)
-------—Pet responses methods--------------—
Definition: Unit.cpp:16694

◆ HandlePetCastSpellOpcode()

void WorldSession::HandlePetCastSpellOpcode ( WorldPacket recvPacket)

Definition at line 1001 of file PetHandler.cpp.

1002{
1003 LOG_DEBUG("network", "WORLD: CMSG_PET_CAST_SPELL");
1004
1005 ObjectGuid guid;
1006 uint8 castCount;
1007 uint32 spellId;
1008 uint8 castFlags;
1009
1010 recvPacket >> guid >> castCount >> spellId >> castFlags;
1011
1012 LOG_DEBUG("network", "WORLD: CMSG_PET_CAST_SPELL, guid: {}, castCount: {}, spellId {}, castFlags {}", guid.ToString(), castCount, spellId, castFlags);
1013
1014 // This opcode is also sent from charmed and possessed units (players and creatures)
1015 if (!_player->GetGuardianPet() && !_player->GetCharm())
1016 return;
1017
1018 Unit* caster = ObjectAccessor::GetUnit(*_player, guid);
1019
1020 if (!caster || (caster != _player->GetGuardianPet() && caster != _player->GetCharm()))
1021 {
1022 LOG_ERROR("network.opcode", "HandlePetCastSpellOpcode: Pet {} isn't pet of player {} .", guid.ToString(), GetPlayer()->GetName());
1023 return;
1024 }
1025
1026 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
1027 if (!spellInfo)
1028 {
1029 LOG_ERROR("network.opcode", "WORLD: unknown PET spell id {}", spellId);
1030 return;
1031 }
1032
1033 // do not cast not learned spells
1034 if (!caster->HasSpell(spellId) || spellInfo->IsPassive())
1035 return;
1036
1037 SpellCastTargets targets;
1038 targets.Read(recvPacket, caster);
1039 HandleClientCastFlags(recvPacket, castFlags, targets);
1040
1041 bool SetFollow = caster->HasUnitState(UNIT_STATE_FOLLOW);
1043
1044 Spell* spell = new Spell(caster, spellInfo, TRIGGERED_NONE);
1045 spell->m_cast_count = castCount; // probably pending spell cast
1046 spell->m_targets = targets;
1047 spell->LoadScripts();
1048
1049 // Xinef: Send default target, fixes return on NeedExplicitUnitTarget
1050 Unit* target = targets.GetUnitTarget();
1051 if (!target && spell->m_spellInfo->NeedsExplicitUnitTarget())
1052 target = _player->GetSelectedUnit();
1053
1054 SpellCastResult result = spell->CheckPetCast(target);
1055
1056 if (result == SPELL_CAST_OK)
1057 {
1058 if (Creature* creature = caster->ToCreature())
1059 {
1060 creature->AddSpellCooldown(spellId, 0, 0);
1061 if (Pet* pet = creature->ToPet())
1062 {
1063 // 10% chance to play special pet attack talk, else growl
1064 // actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell
1065 if (pet->getPetType() == SUMMON_PET && (urand(0, 100) < 10))
1066 pet->SendPetTalk(PET_TALK_SPECIAL_SPELL);
1067 else
1068 pet->SendPetAIReaction(guid);
1069 }
1070 }
1071
1072 spell->prepare(&(spell->m_targets));
1073 }
1074 else
1075 {
1076 if (!caster->GetCharmInfo() || !caster->GetCharmInfo()->GetForcedSpell())
1077 spell->SendPetCastResult(result);
1078
1079 if (caster->GetTypeId() == TYPEID_PLAYER)
1080 {
1081 if (!caster->ToPlayer()->HasSpellCooldown(spellId))
1082 GetPlayer()->SendClearCooldown(spellId, caster);
1083 }
1084 else
1085 {
1086 if (!caster->ToCreature()->HasSpellCooldown(spellId))
1087 GetPlayer()->SendClearCooldown(spellId, caster);
1088
1089 // reset specific flags in case of spell fail. AI will reset other flags
1090 if (caster->IsPet())
1091 caster->PetSpellFail(spellInfo, targets.GetUnitTarget(), result);
1092 }
1093
1094 spell->finish(false);
1095 delete spell;
1096 }
1097
1098 if (SetFollow && !caster->IsInCombat())
1100}
bool HasSpellCooldown(uint32 spell_id) const override
Definition: Player.cpp:16022
Unit * GetSelectedUnit() const
Definition: Player.cpp:11249
Unit * GetCharm() const
Definition: Unit.cpp:10614
virtual bool HasSpell(uint32) const
Definition: Unit.h:1699
void AddUnitState(uint32 f)
Definition: Unit.h:1397
Guardian * GetGuardianPet() const
Definition: Unit.cpp:10599
bool NeedsExplicitUnitTarget() const
Definition: SpellInfo.cpp:1016

◆ HandlePetitionBuyOpcode()

void WorldSession::HandlePetitionBuyOpcode ( WorldPacket recvData)

Definition at line 33 of file PetitionsHandler.cpp.

34{
35 LOG_DEBUG("network", "Received opcode CMSG_PETITION_BUY");
36
37 ObjectGuid guidNPC;
38 uint32 clientIndex; // 1 for guild and arenaslot+1 for arenas in client
39 std::string name;
40
41 recvData >> guidNPC; // NPC GUID
42 recvData.read_skip<uint32>(); // 0
43 recvData.read_skip<uint64>(); // 0
44 recvData >> name; // name
45 recvData.read_skip<std::string>(); // some string
46 recvData.read_skip<uint32>(); // 0
47 recvData.read_skip<uint32>(); // 0
48 recvData.read_skip<uint32>(); // 0
49 recvData.read_skip<uint32>(); // 0
50 recvData.read_skip<uint32>(); // 0
51 recvData.read_skip<uint32>(); // 0
52 recvData.read_skip<uint32>(); // 0
53 recvData.read_skip<uint16>(); // 0
54 recvData.read_skip<uint32>(); // 0
55 recvData.read_skip<uint32>(); // 0
56 recvData.read_skip<uint32>(); // 0
57
58 for (int i = 0; i < 10; ++i)
59 recvData.read_skip<std::string>();
60
61 recvData >> clientIndex; // index
62 recvData.read_skip<uint32>(); // 0
63
64 LOG_DEBUG("network", "Petitioner ({}) tried sell petition: name {}", guidNPC.ToString(), name);
65
66 // prevent cheating
68 if (!creature)
69 {
70 LOG_DEBUG("network", "WORLD: HandlePetitionBuyOpcode - Unit ({}) not found or you can't interact with him.", guidNPC.ToString());
71 return;
72 }
73
74 // remove fake death
75 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
77
78 uint32 charterid = 0;
79 uint32 cost = 0;
80 uint32 type = 0;
81 if (creature->IsTabardDesigner())
82 {
83 // if tabard designer, then trying to buy a guild charter.
84 // do not let if already in guild.
85 if (_player->GetGuildId())
86 return;
87
88 charterid = GUILD_CHARTER;
89 cost = sWorld->getIntConfig(CONFIG_CHARTER_COST_GUILD);
90 type = GUILD_CHARTER_TYPE;
91 }
92 else
93 {
94 // TODO: find correct opcode
95 if (_player->getLevel() < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
96 {
98 return;
99 }
100
101 switch (clientIndex) // arenaSlot+1 as received from client (1 from 3 case)
102 {
103 case 1:
104 charterid = ARENA_TEAM_CHARTER_2v2;
105 cost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_2v2);
107 break;
108 case 2:
109 charterid = ARENA_TEAM_CHARTER_3v3;
110 cost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_3v3);
112 break;
113 case 3:
114 charterid = ARENA_TEAM_CHARTER_5v5;
115 cost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_5v5);
117 break;
118 default:
119 LOG_DEBUG("network", "unknown selection at buy arena petition: {}", clientIndex);
120 return;
121 }
122
123 if (_player->GetArenaTeamId(clientIndex - 1)) // arenaSlot+1 as received from client
124 {
126 return;
127 }
128 }
129
130 sScriptMgr->PetitionBuy(_player, creature, charterid, cost, type);
131
132 if (type == GUILD_CHARTER_TYPE)
133 {
134 if (sGuildMgr->GetGuildByName(name))
135 {
137 return;
138 }
139
140 if (sObjectMgr->IsReservedName(name) || !ObjectMgr::IsValidCharterName(name))
141 {
143 return;
144 }
145 }
146 else
147 {
148 if (sArenaTeamMgr->GetArenaTeamByName(name))
149 {
151 return;
152 }
153 if (sObjectMgr->IsReservedName(name) || !ObjectMgr::IsValidCharterName(name))
154 {
156 return;
157 }
158 }
159
160 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(charterid);
161 if (!pProto)
162 {
163 _player->SendBuyError(BUY_ERR_CANT_FIND_ITEM, nullptr, charterid, 0);
164 return;
165 }
166
167 if (!_player->HasEnoughMoney(cost))
168 {
169 //player hasn't got enough money
170 _player->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, creature, charterid, 0);
171 return;
172 }
173
174 ItemPosCountVec dest;
175 InventoryResult msg = _player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, charterid, pProto->BuyCount);
176 if (msg != EQUIP_ERR_OK)
177 {
178 _player->SendEquipError(msg, nullptr, nullptr, charterid);
179 return;
180 }
181
182 _player->ModifyMoney(-(int32)cost);
183 Item* charter = _player->StoreNewItem(dest, charterid, true);
184 if (!charter)
185 return;
186
188 // ITEM_FIELD_ENCHANTMENT_1_1 is guild/arenateam id
189 // ITEM_FIELD_ENCHANTMENT_1_1+1 is current signatures count (showed on item)
190 charter->SetState(ITEM_CHANGED, _player);
191 _player->SendNewItem(charter, 1, true, false);
192
193 // a petition is invalid, if both the owner and the type matches
194 // we checked above, if this player is in an arenateam, so this must be
195 // datacorruption
196 Petition const* petition = sPetitionMgr->GetPetitionByOwnerWithType(_player->GetGUID(), type);
197
198 CharacterDatabase.EscapeString(name);
199 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
200
201 if (petition)
202 {
203 LOG_DEBUG("network", "Invalid petition: {}", petition->petitionGuid.ToString());
204
205 trans->Append("DELETE FROM petition WHERE petitionguid = {}", petition->petitionGuid.GetCounter());
206 trans->Append("DELETE FROM petition_sign WHERE petitionguid = {}", petition->petitionGuid.GetCounter());
207
208 // xinef: clear petition store
209 sPetitionMgr->RemovePetition(petition->petitionGuid);
210 }
211
212 // xinef: petition pointer is invalid from now on
213
215 stmt->SetData(0, _player->GetGUID().GetCounter());
216 stmt->SetData(1, charter->GetGUID().GetCounter());
217 stmt->SetData(2, name);
218 stmt->SetData(3, uint8(type));
219 trans->Append(stmt);
220
221 CharacterDatabase.CommitTransaction(trans);
222
223 // xinef: fill petition store
224 sPetitionMgr->AddPetition(charter->GetGUID(), _player->GetGUID(), name, uint8(type));
225}
@ CHAR_INS_PETITION
@ ERR_ARENA_TEAM_NAME_INVALID
Definition: ArenaTeam.h:46
@ ERR_ARENA_TEAM_NAME_EXISTS_S
Definition: ArenaTeam.h:47
@ ITEM_FIELD_ENCHANTMENT_1_1
Definition: UpdateFields.h:43
@ UNIT_NPC_FLAG_PETITIONER
Definition: Unit.h:534
@ ERR_GUILD_NAME_EXISTS_S
Definition: Guild.h:129
@ ERR_GUILD_NAME_INVALID
Definition: Guild.h:128
@ GUILD_CHARTER
Definition: PetitionMgr.h:31
@ ARENA_TEAM_CHARTER_2v2
Definition: PetitionMgr.h:32
@ ARENA_TEAM_CHARTER_5v5
Definition: PetitionMgr.h:34
@ ARENA_TEAM_CHARTER_3v3
Definition: PetitionMgr.h:33
@ CONFIG_CHARTER_COST_GUILD
Definition: IWorld.h:385
@ CONFIG_CHARTER_COST_ARENA_5v5
Definition: IWorld.h:388
@ CONFIG_CHARTER_COST_ARENA_2v2
Definition: IWorld.h:386
@ CONFIG_CHARTER_COST_ARENA_3v3
Definition: IWorld.h:387
@ ARENA_TEAM_CHARTER_2v2_TYPE
Definition: WorldSession.h:223
@ ARENA_TEAM_CHARTER_3v3_TYPE
Definition: WorldSession.h:224
@ ARENA_TEAM_CHARTER_5v5_TYPE
Definition: WorldSession.h:225
uint32 BuyCount
Definition: ItemTemplate.h:638
bool IsTabardDesigner() const
Definition: Unit.h:1659
static bool IsValidCharterName(std::string_view name)
Definition: ObjectMgr.cpp:8154
ObjectGuid petitionGuid
Definition: PetitionMgr.h:41

◆ HandlePetitionDeclineOpcode()

void WorldSession::HandlePetitionDeclineOpcode ( WorldPacket recvData)

Definition at line 528 of file PetitionsHandler.cpp.

529{
530 LOG_DEBUG("network", "Received opcode MSG_PETITION_DECLINE"); // ok
531
532 ObjectGuid petitionguid;
533 ObjectGuid ownerguid;
534 recvData >> petitionguid; // petition guid
535 LOG_DEBUG("network", "Petition {} declined by {}", petitionguid.ToString(), _player->GetGUID().ToString());
536
537 Petition const* petition = sPetitionMgr->GetPetition(petitionguid);
538 if (!petition)
539 return;
540
541 if (Player* owner = ObjectAccessor::FindConnectedPlayer(ownerguid)) // petition owner online
542 {
544 data << _player->GetGUID();
545 owner->GetSession()->SendPacket(&data);
546 }
547}
@ MSG_PETITION_DECLINE
Definition: Opcodes.h:480

◆ HandlePetitionQueryOpcode()

void WorldSession::HandlePetitionQueryOpcode ( WorldPacket recvData)

Definition at line 266 of file PetitionsHandler.cpp.

267{
268 LOG_DEBUG("network", "Received opcode CMSG_PETITION_QUERY"); // ok
269
270 ObjectGuid::LowType guildguid;
271 ObjectGuid petitionguid;
272 recvData >> guildguid; // in Trinity always same as petition low guid
273 recvData >> petitionguid; // petition guid
274 LOG_DEBUG("network", "CMSG_PETITION_QUERY Petition ({}) Guild GUID {}", petitionguid.ToString(), guildguid);
275
276 SendPetitionQueryOpcode(petitionguid);
277}
void SendPetitionQueryOpcode(ObjectGuid petitionguid)

◆ HandlePetitionRenameOpcode()

void WorldSession::HandlePetitionRenameOpcode ( WorldPacket recvData)

Definition at line 326 of file PetitionsHandler.cpp.

327{
328 LOG_DEBUG("network", "Received opcode MSG_PETITION_RENAME"); // ok
329
330 ObjectGuid petitionGuid;
331 std::string newName;
332
333 recvData >> petitionGuid; // guid
334 recvData >> newName; // new name
335
336 Item* item = _player->GetItemByGuid(petitionGuid);
337 if (!item)
338 return;
339
340 Petition const* petition = sPetitionMgr->GetPetition(petitionGuid);
341 if (!petition)
342 {
343 LOG_DEBUG("network", "CMSG_PETITION_QUERY failed for petition ({})", petitionGuid.ToString());
344 return;
345 }
346
347 if (petition->petitionType == GUILD_CHARTER_TYPE)
348 {
349 if (sGuildMgr->GetGuildByName(newName))
350 {
352 return;
353 }
354 if (sObjectMgr->IsReservedName(newName) || !ObjectMgr::IsValidCharterName(newName))
355 {
357 return;
358 }
359 }
360 else
361 {
362 if (sArenaTeamMgr->GetArenaTeamByName(newName))
363 {
365 return;
366 }
367 if (sObjectMgr->IsReservedName(newName) || !ObjectMgr::IsValidCharterName(newName))
368 {
370 return;
371 }
372 }
373
375
376 stmt->SetData(0, newName);
377 stmt->SetData(1, petitionGuid.GetCounter());
378
379 CharacterDatabase.Execute(stmt);
380
381 // xinef: update petition container
382 const_cast<Petition*>(petition)->petitionName = newName;
383
384 LOG_DEBUG("network", "Petition ({}) renamed to {}", petitionGuid.ToString(), newName);
385 WorldPacket data(MSG_PETITION_RENAME, (8 + newName.size() + 1));
386 data << petitionGuid;
387 data << newName;
388 SendPacket(&data);
389}
@ CHAR_UPD_PETITION_NAME
@ MSG_PETITION_RENAME
Definition: Opcodes.h:735

◆ HandlePetitionShowListOpcode()

void WorldSession::HandlePetitionShowListOpcode ( WorldPacket recvPacket)

Definition at line 810 of file PetitionsHandler.cpp.

811{
812 LOG_DEBUG("network", "Received CMSG_PETITION_SHOWLIST");
813
814 ObjectGuid guid;
815 recvData >> guid;
816
818}
void SendPetitionShowList(ObjectGuid guid)

◆ HandlePetitionShowSignOpcode()

void WorldSession::HandlePetitionShowSignOpcode ( WorldPacket recvData)

Definition at line 227 of file PetitionsHandler.cpp.

228{
229 LOG_DEBUG("network", "Received opcode CMSG_PETITION_SHOW_SIGNATURES");
230
231 ObjectGuid petitionguid;
232 recvData >> petitionguid; // petition guid
233
234 // solve (possible) some strange compile problems with explicit use petition low guid at some GCC versions (wrong code optimization in compiler?)
235 Petition const* petition = sPetitionMgr->GetPetition(petitionguid);
236 if (!petition)
237 return;
238
239 uint32 type = petition->petitionType;
240
241 // if guild petition and has guild => error, return;
242 if (type == GUILD_CHARTER_TYPE && _player->GetGuildId())
243 return;
244
245 Signatures const* signatures = sPetitionMgr->GetSignature(petitionguid);
246 uint8 signs = signatures ? signatures->signatureMap.size() : 0;
247
248 LOG_DEBUG("network", "CMSG_PETITION_SHOW_SIGNATURES petition {}", petitionguid.ToString());
249
250 WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES, (8 + 8 + 4 + 1 + signs * 12));
251 data << petitionguid; // petition guid
252 data << _player->GetGUID(); // owner guid
253 data << uint32(petitionguid.GetCounter()); // guild guid
254 data << uint8(signs); // sign's count
255
256 if (signs)
257 for (SignatureMap::const_iterator itr = signatures->signatureMap.begin(); itr != signatures->signatureMap.end(); ++itr)
258 {
259 data << itr->first; // Player GUID
260 data << uint32(0); // there 0 ...
261 }
262
263 SendPacket(&data);
264}

◆ HandlePetitionSignOpcode()

void WorldSession::HandlePetitionSignOpcode ( WorldPacket recvData)

Definition at line 391 of file PetitionsHandler.cpp.

392{
393 LOG_DEBUG("network", "Received opcode CMSG_PETITION_SIGN"); // ok
394
395 ObjectGuid petitionGuid;
396 uint8 unk;
397 recvData >> petitionGuid; // petition guid
398 recvData >> unk;
399
400 Petition const* petition = sPetitionMgr->GetPetition(petitionGuid);
401 if (!petition)
402 {
403 LOG_ERROR("network.opcode", "Petition {} is not found for player {} (Name: {})", petitionGuid.ToString(), GetPlayer()->GetGUID().ToString(), GetPlayer()->GetName());
404 return;
405 }
406
407 uint8 type = petition->petitionType;
408
409 ObjectGuid playerGuid = _player->GetGUID();
410 if (petition->ownerGuid == playerGuid)
411 return;
412
413 Signatures const* signatures = sPetitionMgr->GetSignature(petitionGuid);
414 if (!signatures)
415 return;
416
417 // not let enemies sign guild charter
418 if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && GetPlayer()->GetTeamId() != sCharacterCache->GetCharacterTeamByGuid(petition->ownerGuid))
419 {
420 if (type != GUILD_CHARTER_TYPE)
422 else
424 return;
425 }
426
427 if (type != GUILD_CHARTER_TYPE)
428 {
429 if (_player->getLevel() < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
430 {
432 return;
433 }
434
435 uint8 slot = ArenaTeam::GetSlotByType(type);
436 if (slot >= MAX_ARENA_SLOT)
437 return;
438
439 if (_player->GetArenaTeamId(slot))
440 {
442 return;
443 }
444
446 {
448 return;
449 }
450 }
451 else
452 {
453 if (_player->GetGuildId())
454 {
456 return;
457 }
459 {
461 return;
462 }
463 }
464
465 uint32 signs = signatures->signatureMap.size();
466 if (++signs > type) // client signs maximum
467 return;
468
469 // Client doesn't allow to sign petition two times by one character, but not check sign by another character from same account
470 // not allow sign another player from already sign player account
471
472 bool found = false;
473 for (SignatureMap::const_iterator itr = signatures->signatureMap.begin(); itr != signatures->signatureMap.end(); ++itr)
474 if (itr->second == GetAccountId())
475 {
476 found = true;
477 break;
478 }
479
480 if (found)
481 {
482 WorldPacket data(SMSG_PETITION_SIGN_RESULTS, (8 + 8 + 4));
483 data << petitionGuid;
484 data << playerGuid;
486
487 // close at signer side
488 SendPacket(&data);
489
490 // update for owner if online
492 owner->GetSession()->SendPacket(&data);
493 return;
494 }
495
497
498 stmt->SetData(0, petition->ownerGuid.GetCounter());
499 stmt->SetData(1, petitionGuid.GetCounter());
500 stmt->SetData(2, playerGuid.GetCounter());
501 stmt->SetData(3, GetAccountId());
502
503 CharacterDatabase.Execute(stmt);
504
505 // xinef: fill petition store
506 sPetitionMgr->AddSignature(petitionGuid, GetAccountId(), playerGuid);
507
508 LOG_DEBUG("network", "PETITION SIGN: {} by player: {} ({}, Account: {})", petitionGuid.ToString(), _player->GetName(), playerGuid.ToString(), GetAccountId());
509
510 WorldPacket data(SMSG_PETITION_SIGN_RESULTS, (8 + 8 + 4));
511 data << petitionGuid;
512 data << playerGuid;
513 data << uint32(PETITION_SIGN_OK);
514
515 // close at signer side
516 SendPacket(&data);
517
518 // update signs count on charter, required testing...
519 //Item* item = _player->GetItemByGuid(petitionguid));
520 //if (item)
521 // item->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1+1, signs);
522
523 // update for owner if online
525 owner->GetSession()->SendPacket(&data);
526}
@ CHAR_INS_PETITION_SIGNATURE
@ PETITION_SIGN_ALREADY_SIGNED
Definition: Guild.h:182
@ PETITION_SIGN_OK
Definition: Guild.h:181
@ SMSG_PETITION_SIGN_RESULTS
Definition: Opcodes.h:479
ObjectGuid ownerGuid
Definition: PetitionMgr.h:42

◆ HandlePetLearnTalent()

void WorldSession::HandlePetLearnTalent ( WorldPacket recvPacket)

Definition at line 1118 of file PetHandler.cpp.

1119{
1120 LOG_DEBUG("network", "WORLD: CMSG_PET_LEARN_TALENT");
1121
1122 ObjectGuid guid;
1123 uint32 talent_id, requested_rank;
1124 recvData >> guid >> talent_id >> requested_rank;
1125
1126 _player->LearnPetTalent(guid, talent_id, requested_rank);
1128}

◆ HandlePetNameQuery()

void WorldSession::HandlePetNameQuery ( WorldPacket recvData)

Definition at line 600 of file PetHandler.cpp.

601{
602 LOG_DEBUG("network.opcode", "HandlePetNameQuery. CMSG_PET_NAME_QUERY");
603
604 uint32 petnumber;
605 ObjectGuid petguid;
606
607 recvData >> petnumber;
608 recvData >> petguid;
609
610 SendPetNameQuery(petguid, petnumber);
611}
void SendPetNameQuery(ObjectGuid guid, uint32 petnumber)
Definition: PetHandler.cpp:613

◆ HandlePetRename()

void WorldSession::HandlePetRename ( WorldPacket recvData)

Definition at line 824 of file PetHandler.cpp.

825{
826 LOG_DEBUG("network.opcode", "HandlePetRename. CMSG_PET_RENAME");
827
828 ObjectGuid petguid;
829 uint8 isdeclined;
830
831 std::string name;
832 DeclinedName declinedname;
833
834 recvData >> petguid;
835 recvData >> name;
836 recvData >> isdeclined;
837
838 PetStable* petStable = _player->GetPetStable();
839
840 Pet* pet = ObjectAccessor::GetPet(*_player, petguid);
841
842 // check it!
843 if (!pet || !pet->IsPet() || ((Pet*)pet)->getPetType() != HUNTER_PET ||
845 pet->GetOwnerGUID() != _player->GetGUID() || !pet->GetCharmInfo() ||
846 !petStable || !petStable->CurrentPet || petStable->CurrentPet->PetNumber != pet->GetCharmInfo()->GetPetNumber())
847 {
848 return;
849 }
850
852 if (res != PET_NAME_SUCCESS)
853 {
854 SendPetNameInvalid(res, name, nullptr);
855 return;
856 }
857
858 if (sObjectMgr->IsReservedName(name))
859 {
861 return;
862 }
863
864 pet->SetName(name);
865
866 Unit* owner = pet->GetOwner();
867 if (owner && (owner->GetTypeId() == TYPEID_PLAYER) && owner->ToPlayer()->GetGroup())
869
871
872 petStable->CurrentPet->Name = name;
873 petStable->CurrentPet->WasRenamed = true;
874
875 if (isdeclined)
876 {
877 for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
878 {
879 recvData >> declinedname.name[i];
880 }
881
882 std::wstring wname;
883 Utf8toWStr(name, wname);
884 if (!ObjectMgr::CheckDeclinedNames(wname, declinedname))
885 {
887 return;
888 }
889 }
890
891 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
892 if (isdeclined)
893 {
894 if (sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED))
895 {
897 stmt->SetData(0, pet->GetCharmInfo()->GetPetNumber());
898 trans->Append(stmt);
899
900 stmt = CharacterDatabase.GetPreparedStatement(CHAR_ADD_CHAR_PET_DECLINEDNAME);
901 stmt->SetData(0, _player->GetGUID().GetCounter());
902
903 for (uint8 i = 0; i < 5; i++)
904 stmt->SetData(i + 1, declinedname.name[i]);
905
906 trans->Append(stmt);
907 }
908 }
909
911 stmt->SetData(0, name);
912 stmt->SetData(1, _player->GetGUID().GetCounter());
913 stmt->SetData(2, pet->GetCharmInfo()->GetPetNumber());
914 trans->Append(stmt);
915
916 CharacterDatabase.CommitTransaction(trans);
917
918 pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(GameTime::GetGameTime().count())); // cast can't be helped
919}
bool Utf8toWStr(char const *utf8str, size_t csize, wchar_t *wstr, size_t &wsize)
Definition: Util.cpp:282
@ CHAR_ADD_CHAR_PET_DECLINEDNAME
@ CHAR_UPD_CHAR_PET_NAME
@ CHAR_DEL_CHAR_PET_DECLINEDNAME
@ UNIT_FIELD_PET_NAME_TIMESTAMP
Definition: UpdateFields.h:133
@ UNIT_CAN_BE_RENAMED
Definition: Unit.h:149
#define MAX_DECLINED_NAME_CASES
Definition: Unit.h:969
PetNameInvalidReason
@ PET_NAME_RESERVED
@ PET_NAME_SUCCESS
@ PET_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME
Pet * GetPet(WorldObject const &, ObjectGuid const guid)
void SetName(std::string const &newname)
Definition: Object.h:447
Optional< PetInfo > CurrentPet
Definition: PetDefines.h:220
void SetGroupUpdateFlag(uint32 flag)
Definition: Player.h:2423
PetStable * GetPetStable()
Definition: Player.h:1178
std::string name[MAX_DECLINED_NAME_CASES]
Definition: Unit.h:973
uint32 GetPetNumber() const
Definition: Unit.h:1099
static PetNameInvalidReason CheckPetName(std::string_view name)
Definition: ObjectMgr.cpp:8186
static bool CheckDeclinedNames(std::wstring w_ownname, DeclinedName const &names)
Definition: ObjectMgr.cpp:8380
void SendPetNameInvalid(uint32 error, std::string const &name, DeclinedName *declinedName)

◆ HandlePetSetAction()

void WorldSession::HandlePetSetAction ( WorldPacket recvData)

Definition at line 680 of file PetHandler.cpp.

681{
682 LOG_DEBUG("network.opcode", "HandlePetSetAction. CMSG_PET_SET_ACTION");
683
684 ObjectGuid petguid;
685 uint8 count;
686
687 recvData >> petguid;
688
689 Unit* checkPet = ObjectAccessor::GetUnit(*_player, petguid);
690 if (!checkPet || checkPet != _player->GetFirstControlled())
691 {
692 LOG_ERROR("network.opcode", "HandlePetSetAction: Unknown pet ({}) or pet owner ({})", petguid.ToString(), _player->GetGUID().ToString());
693 return;
694 }
695
696 count = (recvData.size() == 24) ? 2 : 1;
697
698 uint32 position[2];
699 uint32 data[2];
700 bool move_command = false;
701
702 for (uint8 i = 0; i < count; ++i)
703 {
704 recvData >> position[i];
705 recvData >> data[i];
706
707 uint8 act_state = UNIT_ACTION_BUTTON_TYPE(data[i]);
708
709 //ignore invalid position
710 if (position[i] >= MAX_UNIT_ACTION_BAR_INDEX)
711 return;
712
713 // in the normal case, command and reaction buttons can only be moved, not removed
714 // at moving count == 2, at removing count == 1
715 // ignore attempt to remove command|reaction buttons (not possible at normal case)
716 if (act_state == ACT_COMMAND || act_state == ACT_REACTION)
717 {
718 if (count == 1)
719 return;
720
721 move_command = true;
722 }
723 }
724
725 Unit::ControlSet petsSet;
726 if (checkPet->GetEntry() != petguid.GetEntry())
727 petsSet.insert(checkPet);
728 else
729 petsSet = _player->m_Controlled;
730
731 // Xinef: loop all pets with same entry (fixes partial state change for feral spirits)
732 for (Unit::ControlSet::const_iterator itr = petsSet.begin(); itr != petsSet.end(); ++itr)
733 {
734 Unit* pet = *itr;
735 if (checkPet->GetEntry() == petguid.GetEntry() && pet->GetEntry() != petguid.GetEntry())
736 continue;
737
738 CharmInfo* charmInfo = pet->GetCharmInfo();
739 if (!charmInfo)
740 {
741 LOG_ERROR("network.opcode", "WorldSession::HandlePetSetAction: object ({} TypeId: {}) is considered pet-like but doesn't have a charminfo!",
742 pet->GetGUID().ToString(), pet->GetTypeId());
743 continue;
744 }
745
746 // check swap (at command->spell swap client remove spell first in another packet, so check only command move correctness)
747 if (move_command)
748 {
749 uint8 act_state_0 = UNIT_ACTION_BUTTON_TYPE(data[0]);
750 if (act_state_0 == ACT_COMMAND || act_state_0 == ACT_REACTION)
751 {
752 uint32 spell_id_0 = UNIT_ACTION_BUTTON_ACTION(data[0]);
753 UnitActionBarEntry const* actionEntry_1 = charmInfo->GetActionBarEntry(position[1]);
754 if (!actionEntry_1 || spell_id_0 != actionEntry_1->GetAction() ||
755 act_state_0 != actionEntry_1->GetType())
756 continue;
757 }
758
759 uint8 act_state_1 = UNIT_ACTION_BUTTON_TYPE(data[1]);
760 if (act_state_1 == ACT_COMMAND || act_state_1 == ACT_REACTION)
761 {
762 uint32 spell_id_1 = UNIT_ACTION_BUTTON_ACTION(data[1]);
763 UnitActionBarEntry const* actionEntry_0 = charmInfo->GetActionBarEntry(position[0]);
764 if (!actionEntry_0 || spell_id_1 != actionEntry_0->GetAction() ||
765 act_state_1 != actionEntry_0->GetType())
766 continue;
767 }
768 }
769
770 for (uint8 i = 0; i < count; ++i)
771 {
772 uint32 spell_id = UNIT_ACTION_BUTTON_ACTION(data[i]);
773 uint8 act_state = UNIT_ACTION_BUTTON_TYPE(data[i]);
774
775 //if it's act for spell (en/disable/cast) and there is a spell given (0 = remove spell) which pet doesn't know, don't add
776 if (!((act_state == ACT_ENABLED || act_state == ACT_DISABLED || act_state == ACT_PASSIVE) && spell_id && !pet->HasSpell(spell_id)))
777 {
778 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id))
779 {
780 //sign for autocast
781 if (act_state == ACT_ENABLED)
782 {
783 if (pet->GetTypeId() == TYPEID_UNIT && pet->IsPet())
784 {
785 ((Pet*)pet)->ToggleAutocast(spellInfo, true);
786 }
787 else
788 {
789 for (auto iterator = GetPlayer()->m_Controlled.begin(); iterator != GetPlayer()->m_Controlled.end(); ++iterator)
790 {
791 if ((*iterator)->GetEntry() == pet->GetEntry())
792 {
793 (*iterator)->GetCharmInfo()->ToggleCreatureAutocast(spellInfo, true);
794 }
795 }
796 }
797 }
798 //sign for no/turn off autocast
799 else if (act_state == ACT_DISABLED)
800 {
801 if (pet->GetTypeId() == TYPEID_UNIT && pet->IsPet())
802 {
803 ((Pet*)pet)->ToggleAutocast(spellInfo, false);
804 }
805 else
806 {
807 for (auto iterator = GetPlayer()->m_Controlled.begin(); iterator != GetPlayer()->m_Controlled.end(); ++iterator)
808 {
809 if ((*iterator)->GetEntry() == pet->GetEntry())
810 {
811 (*iterator)->GetCharmInfo()->ToggleCreatureAutocast(spellInfo, false);
812 }
813 }
814 }
815 }
816 }
817
818 charmInfo->SetActionBar(position[i], spell_id, ActiveStates(act_state));
819 }
820 }
821 }
822}
#define MAX_UNIT_ACTION_BAR_INDEX
Definition: Unit.h:1091
ActiveStates
Definition: Unit.h:1012
uint32 GetEntry() const
Definition: ObjectGuid.h:146
ActiveStates GetType() const
Definition: Unit.h:1047
uint32 GetAction() const
Definition: Unit.h:1048
void SetActionBar(uint8 index, uint32 spellOrAction, ActiveStates type)
Definition: Unit.h:1117
UnitActionBarEntry const * GetActionBarEntry(uint8 index) const
Definition: Unit.h:1121
std::set< Unit * > ControlSet
Definition: Unit.h:1293
Unit * GetFirstControlled() const
Definition: Unit.cpp:11023

◆ HandlePetSpellAutocastOpcode()

void WorldSession::HandlePetSpellAutocastOpcode ( WorldPackets::Pet::PetSpellAutocast packet)

Definition at line 945 of file PetHandler.cpp.

946{
948 if (!checkPet)
949 {
950 LOG_ERROR("entities.pet", "WorldSession::HandlePetSpellAutocastOpcode: Pet %s not found.", packet.PetGUID.ToString().c_str());
951 return;
952 }
953
954 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(packet.SpellID);
955 if (!spellInfo)
956 {
957 LOG_ERROR("spells.pet", "WorldSession::HandlePetSpellAutocastOpcode: Unknown spell id %u used by %s.", packet.SpellID, packet.PetGUID.ToString().c_str());
958 return;
959 }
960
961 if (checkPet != _player->GetGuardianPet() && checkPet != _player->GetCharm())
962 {
963 LOG_ERROR("entities.pet", "WorldSession::HandlePetSpellAutocastOpcode: %s isn't pet of player %s (%s).",
964 packet.PetGUID.ToString().c_str(), GetPlayer()->GetName().c_str(), GetPlayer()->GetGUID().ToString().c_str());
965 return;
966 }
967
968 Unit::ControlSet petsSet;
969 if (checkPet->GetEntry() != packet.PetGUID.GetEntry())
970 petsSet.insert(checkPet);
971 else
972 petsSet = _player->m_Controlled;
973
974 // Xinef: loop all pets with same entry (fixes partial state change for feral spirits)
975 for (Unit* pet : petsSet)
976 {
977 if (checkPet->GetEntry() == packet.PetGUID.GetEntry() && pet->GetEntry() != packet.PetGUID.GetEntry())
978 continue;
979
980 // do not add not learned spells/ passive spells
981 if (!pet->HasSpell(packet.SpellID) || !spellInfo->IsAutocastable())
982 continue;
983
984 CharmInfo* charmInfo = pet->GetCharmInfo();
985 if (!charmInfo)
986 {
987 LOG_ERROR("network.opcode", "WorldSession::HandlePetSpellAutocastOpcode: object ({} TypeId: {}) is considered pet-like but doesn't have a charminfo!",
988 pet->GetGUID().ToString(), pet->GetTypeId());
989 continue;
990 }
991
992 if (Pet* summon = pet->ToPet())
993 summon->ToggleAutocast(spellInfo, packet.AutocastEnabled);
994 else
995 charmInfo->ToggleCreatureAutocast(spellInfo, packet.AutocastEnabled);
996
997 charmInfo->SetSpellAutocast(spellInfo, packet.AutocastEnabled);
998 }
999}
void SetSpellAutocast(SpellInfo const *spellInfo, bool state)
Definition: Unit.cpp:15915
void ToggleCreatureAutocast(SpellInfo const *spellInfo, bool apply)
Definition: Unit.cpp:15854
bool IsAutocastable() const
Definition: SpellInfo.cpp:1086

◆ HandlePetStopAttack()

void WorldSession::HandlePetStopAttack ( WorldPackets::Pet::PetStopAttack packet)

Definition at line 127 of file PetHandler.cpp.

128{
130
131 if (!pet)
132 {
133 LOG_ERROR("network.opcode", "HandlePetStopAttack: Pet {} does not exist", packet.PetGUID.ToString());
134 return;
135 }
136
137 if (pet != GetPlayer()->GetPet() && pet != GetPlayer()->GetCharm())
138 {
139 LOG_ERROR("network.opcode", "HandlePetStopAttack: Pet {} isn't a pet or charmed creature of player {}", packet.PetGUID.ToString(), GetPlayer()->GetName());
140 return;
141 }
142
143 if (!pet->IsAlive())
144 return;
145
146 pet->AttackStop();
147 pet->ClearInPetCombat();
148}

◆ HandlePlayedTime()

void WorldSession::HandlePlayedTime ( WorldPackets::Character::PlayedTimeClient packet)

Definition at line 1022 of file MiscHandler.cpp.

◆ HandlePlayerLoginFromDB()

void WorldSession::HandlePlayerLoginFromDB ( LoginQueryHolder const &  holder)

Definition at line 791 of file CharacterHandler.cpp.

792{
793 ObjectGuid playerGuid = holder.GetGuid();
794
795 Player* pCurrChar = new Player(this);
796 // for send server info and strings (config)
797 ChatHandler chH = ChatHandler(pCurrChar->GetSession());
798
799 // "GetAccountId() == db stored account id" checked in LoadFromDB (prevent login not own character using cheating tools)
800 if (!pCurrChar->LoadFromDB(playerGuid, holder))
801 {
802 SetPlayer(nullptr);
803 KickPlayer("WorldSession::HandlePlayerLogin Player::LoadFromDB failed"); // disconnect client, player no set to session and it will not deleted or saved at kick
804 delete pCurrChar; // delete it manually
805 m_playerLoading = false;
806 return;
807 }
808
809 pCurrChar->GetMotionMaster()->Initialize();
810 pCurrChar->SendDungeonDifficulty(false);
811
813 data << pCurrChar->GetMapId();
814 data << pCurrChar->GetPositionX();
815 data << pCurrChar->GetPositionY();
816 data << pCurrChar->GetPositionZ();
817 data << pCurrChar->GetOrientation();
818 SendPacket(&data);
819
820 // load player specific part before send times
823
824 data.Initialize(SMSG_FEATURE_SYSTEM_STATUS, 2); // added in 2.2.0
825 data << uint8(2); // 2 - COMPLAINT_ENABLED_WITH_AUTO_IGNORE
826 data << uint8(0); // enable(1)/disable(0) voice chat interface in client
827 SendPacket(&data);
828
829 // Send MOTD
830 {
832
833 // send server info
834 if (sWorld->getIntConfig(CONFIG_ENABLE_SINFO_LOGIN) == 1)
836 }
837
838 if (uint32 guildId = sCharacterCache->GetCharacterGuildIdByGuid(pCurrChar->GetGUID()))
839 {
840 Guild* guild = sGuildMgr->GetGuildById(guildId);
841 Guild::Member const* member = guild ? guild->GetMember(pCurrChar->GetGUID()) : nullptr;
842 if (member)
843 {
844 pCurrChar->SetInGuild(guildId);
845 pCurrChar->SetRank(member->GetRankId());
846 guild->SendLoginInfo(this);
847 }
848 else
849 {
850 LOG_ERROR("network.opcode", "Player {} ({}) marked as member of not existing guild (id: {}), removing guild membership for player.",
851 pCurrChar->GetName(), pCurrChar->GetGUID().ToString(), guildId);
852 pCurrChar->SetInGuild(0);
853 pCurrChar->SetRank(0);
854 }
855 }
856 else
857 {
858 pCurrChar->SetInGuild(0);
859 pCurrChar->SetRank(0);
860 }
861
862 data.Initialize(SMSG_LEARNED_DANCE_MOVES, 4 + 4);
863 data << uint32(0);
864 data << uint32(0);
865 SendPacket(&data);
866
868
869 //Show cinematic at the first time that player login
870 if (!pCurrChar->getCinematic())
871 {
872 pCurrChar->setCinematic(1);
873
874 if (ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(pCurrChar->getClass()))
875 {
876 if (cEntry->CinematicSequence)
877 pCurrChar->SendCinematicStart(cEntry->CinematicSequence);
878 else if (ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(pCurrChar->getRace()))
879 pCurrChar->SendCinematicStart(rEntry->CinematicSequence);
880
881 // send new char string if not empty
882 if (!sWorld->GetNewCharString().empty())
883 chH.PSendSysMessage("%s", sWorld->GetNewCharString().c_str());
884 }
885 }
886
887 // Xinef: moved this from below
888 ObjectAccessor::AddObject(pCurrChar);
889
890 if (!pCurrChar->GetMap()->AddPlayerToMap(pCurrChar) || !pCurrChar->CheckInstanceLoginValid())
891 {
892 AreaTriggerTeleport const* at = sObjectMgr->GetGoBackTrigger(pCurrChar->GetMapId());
893 if (at)
894 pCurrChar->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, pCurrChar->GetOrientation());
895 else
896 pCurrChar->TeleportTo(pCurrChar->m_homebindMapId, pCurrChar->m_homebindX, pCurrChar->m_homebindY, pCurrChar->m_homebindZ, pCurrChar->m_homebindO);
897 }
898
900
902 stmt->SetData(0, pCurrChar->GetGUID().GetCounter());
903 CharacterDatabase.Execute(stmt);
904
906 loginStmt->SetData(0, realm.Id.Realm);
907 loginStmt->SetData(1, GetAccountId());
908 LoginDatabase.Execute(loginStmt);
909
910 pCurrChar->SetInGameTime(GameTime::GetGameTimeMS().count());
911
912 // announce group about member online (must be after add to player list to receive announce to self)
913 if (Group* group = pCurrChar->GetGroup())
914 {
915 group->SendUpdate();
916 group->ResetMaxEnchantingLevel();
917 }
918
919 // pussywizard: send instance welcome message as when entering the instance through a portal
920 if (MapDifficulty const* mapDiff = GetMapDifficultyData(pCurrChar->GetMap()->GetId(), pCurrChar->GetMap()->GetDifficulty()))
921 if (mapDiff->resetTime)
922 if (time_t timeReset = sInstanceSaveMgr->GetResetTimeFor(pCurrChar->GetMap()->GetId(), pCurrChar->GetMap()->GetDifficulty()))
923 {
924 uint32 timeleft = uint32(timeReset - GameTime::GetGameTime().count());
925 pCurrChar->SendInstanceResetWarning(pCurrChar->GetMap()->GetId(), pCurrChar->GetMap()->GetDifficulty(), timeleft, true);
926 }
927
928 // pussywizard: ensure that we end up on map with our loaded transport:
929 if (Transport* t = pCurrChar->GetTransport())
930 if (!t->IsInMap(pCurrChar))
931 {
932 t->RemovePassenger(pCurrChar);
933 pCurrChar->m_transport = nullptr;
934 pCurrChar->m_movementInfo.transport.Reset();
936 }
937
938 // friend status
939 sSocialMgr->SendFriendStatus(pCurrChar, FRIEND_ONLINE, pCurrChar->GetGUID(), true);
940
941 // Place character in world (and load zone) before some object loading
942 pCurrChar->LoadCorpse(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_CORPSE_LOCATION));
943
944 // setting Ghost+speed if dead
945 if (pCurrChar->m_deathState != ALIVE)
946 {
947 // not blizz like, we must correctly save and load player instead...
948 if (pCurrChar->getRace() == RACE_NIGHTELF)
949 pCurrChar->CastSpell(pCurrChar, 20584, true, 0); // auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form)
950
951 pCurrChar->CastSpell(pCurrChar, 8326, true, 0); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?)
952 pCurrChar->SetMovement(MOVE_WATER_WALK);
953 }
954
955 // Set FFA PvP for non GM in non-rest mode
956 if (sWorld->IsFFAPvPRealm() && !pCurrChar->IsGameMaster() && !pCurrChar->HasPlayerFlag(PLAYER_FLAGS_RESTING))
958 {
959 sScriptMgr->OnFfaPvpStateUpdate(pCurrChar,true);
961 }
962
964 {
965 pCurrChar->SetContestedPvP(nullptr, false);
966 }
967
968 // Apply at_login requests
970 {
971 pCurrChar->resetSpells();
973 }
974
976 {
977 pCurrChar->resetTalents(true);
978 pCurrChar->SendTalentsInfoData(false); // original talents send already in to SendInitialPacketsBeforeAddToMap, resend reset state
980 }
981
983 {
985 pCurrChar->CheckAllAchievementCriteria();
986 }
987
988 bool firstLogin = pCurrChar->HasAtLoginFlag(AT_LOGIN_FIRST);
989 if (firstLogin)
990 {
991 PlayerInfo const* info = sObjectMgr->GetPlayerInfo(pCurrChar->getRace(), pCurrChar->getClass());
992 for (uint32 spellId : info->castSpells)
993 {
994 pCurrChar->CastSpell(pCurrChar, spellId, true);
995 }
996
997 // start with every map explored
998 if (sWorld->getBoolConfig(CONFIG_START_ALL_EXPLORED))
999 {
1000 for (uint8 i = 0; i < PLAYER_EXPLORED_ZONES_SIZE; i++)
1001 {
1002 pCurrChar->SetFlag(PLAYER_EXPLORED_ZONES_1 + i, 0xFFFFFFFF);
1003 }
1004 }
1005
1006 // Reputations if "StartAllReputation" is enabled, -- TODO: Fix this in a better way
1007 if (sWorld->getBoolConfig(CONFIG_START_ALL_REP))
1008 {
1009 ReputationMgr& repMgr = pCurrChar->GetReputationMgr();
1010
1011 auto SendFullReputation = [&repMgr](std::initializer_list<uint32> factionsList)
1012 {
1013 for (auto const& itr : factionsList)
1014 {
1015 repMgr.SetOneFactionReputation(sFactionStore.LookupEntry(itr), 42999.f, false);
1016 }
1017 };
1018
1019 SendFullReputation({ 942, 935, 936, 1011, 970, 967, 989, 932, 934, 1038, 1077, 1106, 1104, 1090, 1098, 1156, 1073, 1105, 1119, 1091 });
1020
1021 switch (pCurrChar->GetFaction())
1022 {
1023 case ALLIANCE:
1024 SendFullReputation({ 72, 47, 69, 930, 730, 978, 54, 946, 1037, 1068, 1126, 1094, 1050 });
1025 break;
1026 case HORDE:
1027 SendFullReputation({ 76, 68, 81, 911, 729, 941, 530, 947, 1052, 1067, 1124, 1064, 1085 });
1028 break;
1029 default:
1030 break;
1031 }
1032
1033 repMgr.SendStates();
1034 }
1035 }
1036
1037 // show time before shutdown if shutdown planned.
1038 if (sWorld->IsShuttingDown())
1039 sWorld->ShutdownMsg(true, pCurrChar);
1040
1041 if (sWorld->getBoolConfig(CONFIG_ALL_TAXI_PATHS))
1042 pCurrChar->SetTaxiCheater(true);
1043
1044 if (pCurrChar->IsGameMaster())
1046
1047 std::string IP_str = GetRemoteAddress();
1048 LOG_INFO("entities.player", "Account: {} (IP: {}) Login Character:[{}] ({}) Level: {}",
1049 GetAccountId(), IP_str, pCurrChar->GetName(), pCurrChar->GetGUID().ToString(), pCurrChar->getLevel());
1050
1051 if (!pCurrChar->IsStandState() && !pCurrChar->HasUnitState(UNIT_STATE_STUNNED))
1053
1054 m_playerLoading = false;
1055
1056 // Handle Login-Achievements (should be handled after loading)
1058
1059 // Xinef: fix vendors falling of player vehicle, due to isBeingLoaded checks
1060 if (pCurrChar->IsInWorld())
1061 {
1062 if (pCurrChar->GetMountBlockId() && !pCurrChar->HasAuraType(SPELL_AURA_MOUNTED))
1063 {
1064 pCurrChar->CastSpell(pCurrChar, pCurrChar->GetMountBlockId(), true);
1065 pCurrChar->SetMountBlockId(0);
1066
1067 // Xinef: refresh this in case mount aura changes anything (eg no fly zone)
1068 pCurrChar->UpdateAreaDependentAuras(pCurrChar->GetAreaId());
1069 pCurrChar->UpdateZoneDependentAuras(pCurrChar->GetZoneId());
1070 }
1071 }
1072
1073 // pussywizard: pvp mode
1075 if (pCurrChar->HasPlayerFlag(PLAYER_FLAGS_IN_PVP))
1076 pCurrChar->UpdatePvP(true, true);
1077
1078 // pussywizard: on login it's not possible to go back to arena as a spectator, HandleMoveWorldportAckOpcode is not sent, so call it here
1079 pCurrChar->SetIsSpectator(false);
1080
1081 // xinef: do this after everything is loaded
1082 pCurrChar->ContinueTaxiFlight();
1083
1084 // reset for all pets before pet loading
1087
1088 // Load pet if any (if player not alive and in taxi flight or another then pet will remember as temporary unsummoned)
1089 pCurrChar->LoadPet();
1090
1091 if (pCurrChar->GetSession()->GetRecruiterId() != 0 || pCurrChar->GetSession()->IsARecruiter())
1092 {
1093 bool isReferrer = pCurrChar->GetSession()->IsARecruiter();
1094
1095 for (auto const& [accID, session] : sWorld->GetAllSessions())
1096 {
1097 if (!session->GetRecruiterId() && !session->IsARecruiter())
1098 continue;
1099
1100 if ((isReferrer && pCurrChar->GetSession()->GetAccountId() == session->GetRecruiterId()) || (!isReferrer && pCurrChar->GetSession()->GetRecruiterId() == session->GetAccountId()))
1101 {
1102 Player* rf = session->GetPlayer();
1103 if (rf)
1104 {
1105 pCurrChar->SendUpdateToPlayer(rf);
1106 rf->SendUpdateToPlayer(pCurrChar);
1107 }
1108 }
1109 }
1110 }
1111
1112 sScriptMgr->OnPlayerLogin(pCurrChar);
1113
1114 if (pCurrChar->HasAtLoginFlag(AT_LOGIN_FIRST))
1115 {
1117 sScriptMgr->OnFirstLogin(pCurrChar);
1118 }
1119
1120 METRIC_EVENT("player_events", "Login", pCurrChar->GetName());
1121}
#define METRIC_EVENT(category, title, description)
Definition: Metric.h:187
@ CHAR_UPD_CHAR_ONLINE
@ LOGIN_UPD_ACCOUNT_ONLINE
Definition: LoginDatabase.h:75
@ PLAYER_EXPLORED_ZONES_1
Definition: UpdateFields.h:357
@ PLAYER_FLAGS_CONTESTED_PVP
Definition: Player.h:483
@ PLAYER_FLAGS_PVP_TIMER
Definition: Player.h:493
@ MOVE_WATER_WALK
Definition: Player.h:459
@ AT_LOGIN_RESET_TALENTS
Definition: Player.h:603
@ AT_LOGIN_RESET_SPELLS
Definition: Player.h:602
@ AT_LOGIN_RESET_PET_TALENTS
Definition: Player.h:605
#define PLAYER_EXPLORED_ZONES_SIZE
Definition: Player.h:73
@ PLAYER_LOGIN_QUERY_LOAD_ACCOUNT_DATA
Definition: Player.h:877
@ PLAYER_LOGIN_QUERY_LOAD_CORPSE_LOCATION
Definition: Player.h:887
@ FRIEND_ONLINE
Definition: SocialMgr.h:69
@ ALIVE
Definition: Unit.h:316
@ LANG_RESET_SPELLS
Definition: Language.h:254
@ LANG_RESET_TALENTS
Definition: Language.h:255
@ LANG_GM_ON
Definition: Language.h:373
@ CONFIG_ENABLE_SINFO_LOGIN
Definition: IWorld.h:328
@ CONFIG_ALL_TAXI_PATHS
Definition: IWorld.h:87
@ CONFIG_START_ALL_REP
Definition: IWorld.h:131
@ CONFIG_START_ALL_EXPLORED
Definition: IWorld.h:130
@ ACHIEVEMENT_CRITERIA_TYPE_ON_LOGIN
Definition: DBCEnums.h:190
@ ALLIANCE
@ HORDE
#define PER_CHARACTER_CACHE_MASK
Definition: WorldSession.h:179
@ SMSG_LEARNED_DANCE_MOVES
Definition: Opcodes.h:1139
@ SMSG_LOGIN_VERIFY_WORLD
Definition: Opcodes.h:596
@ SMSG_FEATURE_SYSTEM_STATUS
Definition: Opcodes.h:999
AC_COMMON_API char const * GetFullVersion()
Definition: GitRevision.cpp:70
void AddObject(T *object)
WorldPacket const * GetMotdPacket()
Get the motd packet to send at login.
Definition: ServerMotd.cpp:68
void SetByteFlag(uint16 index, uint8 offset, uint8 newFlag)
Definition: Object.cpp:911
static void resetTalentsForAllPetsOf(Player *owner, Pet *online_pet=nullptr)
Definition: Pet.cpp:2102
PlayerCreateInfoSpells castSpells
Definition: Player.h:350
void RemoveAtLoginFlag(AtLoginFlags flags, bool persist=false)
Definition: Player.cpp:14328
void RemovePlayerFlag(PlayerFlags flags)
Definition: Player.h:1092
uint32 GetMountBlockId()
Definition: Player.h:2549
void ContinueTaxiFlight()
Definition: Player.cpp:10171
void SendDungeonDifficulty(bool IsInGroup)
Definition: PlayerMisc.cpp:167
void UpdateAreaDependentAuras(uint32 area_id)
void SetMountBlockId(uint32 mount)
Definition: Player.h:2550
bool resetTalents(bool noResetCost=false)
Definition: Player.cpp:3635
void LoadCorpse(PreparedQueryResult result)
void SendCinematicStart(uint32 CinematicSequenceId) const
Definition: Player.cpp:5583
void LoadPet()
uint8 getCinematic() const
Definition: Player.h:1780
void SetRank(uint8 rankId)
Definition: Player.h:1847
bool LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const &holder)
void UpdateZoneDependentAuras(uint32 zone_id)
bool HasAtLoginFlag(AtLoginFlags f) const
Definition: Player.h:2351
void SetMovement(PlayerMovementType pType)
Definition: Player.cpp:4280
void SetTaxiCheater(bool on)
Definition: Player.h:1141
void SetInGameTime(uint32 time)
Definition: Player.h:1518
void CheckAllAchievementCriteria()
Definition: Player.cpp:13591
void setCinematic(uint8 cine)
Definition: Player.h:1784
bool CheckInstanceLoginValid()
void resetSpells()
Definition: Player.cpp:11530
void SetContestedPvP(Player *attackedPlayer=nullptr, bool lookForNearContestedGuards=true)
Definition: Unit.cpp:17309
DeathState m_deathState
Definition: Unit.h:2483
bool IsStandState() const
Definition: Unit.cpp:16806
void SendLoginInfo(WorldSession *session)
Definition: Guild.cpp:1851
const Member * GetMember(ObjectGuid guid) const
Definition: Guild.h:377
uint8 GetRankId() const
Definition: Guild.h:332
virtual bool AddPlayerToMap(Player *)
Definition: Map.cpp:506
void Initialize()
bool SetOneFactionReputation(FactionEntry const *factionEntry, float standing, bool incremental, Optional< ReputationRank > repMaxCap={ })
Public for chat command needs.
void SetPlayer(Player *player)
void LoadAccountData(PreparedQueryResult result, uint32 mask)
bool IsARecruiter() const
Definition: WorldSession.h:524
void SendAccountDataTimes(uint32 mask)

◆ HandlePlayerLoginOpcode()

void WorldSession::HandlePlayerLoginOpcode ( WorldPacket recvPacket)

Definition at line 665 of file CharacterHandler.cpp.

666{
667 m_playerLoading = true;
668 ObjectGuid playerGuid;
669 recvData >> playerGuid;
670
671 if (PlayerLoading() || GetPlayer() != nullptr || !playerGuid.IsPlayer())
672 {
673 // limit player interaction with the world
674 if (!sWorld->getBoolConfig(CONFIG_REALM_LOGIN_ENABLED))
675 {
677 // see LoginFailureReason enum for more reasons
678 data << uint8(LoginFailureReason::NoWorld);
679 SendPacket(&data);
680 return;
681 }
682 }
683
684 if (!playerGuid.IsPlayer() || !IsLegitCharacterForAccount(playerGuid))
685 {
686 LOG_ERROR("network", "Account ({}) can't login with that character ({}).", GetAccountId(), playerGuid.ToString());
687 KickPlayer("Account can't login with this character");
688 return;
689 }
690
691 auto SendCharLogin = [&](ResponseCodes result)
692 {
694 data << uint8(result);
695 SendPacket(&data);
696 };
697
698 // pussywizard:
699 if (WorldSession* sess = sWorld->FindOfflineSessionForCharacterGUID(playerGuid.GetCounter()))
700 if (sess->GetAccountId() != GetAccountId())
701 {
702 SendCharLogin(CHAR_LOGIN_DUPLICATE_CHARACTER);
703 return;
704 }
705 // pussywizard:
706 if (WorldSession* sess = sWorld->FindOfflineSession(GetAccountId()))
707 {
708 Player* p = sess->GetPlayer();
709 if (!p || sess->IsKicked())
710 {
711 SendCharLogin(CHAR_LOGIN_DUPLICATE_CHARACTER);
712 return;
713 }
714
715 if (p->GetGUID() != playerGuid)
716 sess->KickPlayer("No return, go to normal loading"); // no return, go to normal loading
717 else
718 {
719 // pussywizard: players stay ingame no matter what (prevent abuse), but allow to turn it off to stop crashing
720 if (!sWorld->getBoolConfig(CONFIG_ENABLE_LOGIN_AFTER_DC))
721 {
722 SendCharLogin(CHAR_LOGIN_DUPLICATE_CHARACTER);
723 return;
724 }
725
726 uint8 limitA = 10, limitB = 10, limitC = 10; // pussywizard: this somehow froze (probably, ahh crash logs ...), and while (far) have never frozen in LogoutPlayer o_O maybe it's the combination of while(far); while(near);
727 while (sess->GetPlayer() && (sess->GetPlayer()->IsBeingTeleportedFar() || (sess->GetPlayer()->IsInWorld() && sess->GetPlayer()->IsBeingTeleportedNear())))
728 {
729 if (limitA == 0 || --limitA == 0)
730 {
731 LOG_INFO("misc", "HandlePlayerLoginOpcode A");
732 break;
733 }
734 while (sess->GetPlayer() && sess->GetPlayer()->IsBeingTeleportedFar())
735 {
736 if (limitB == 0 || --limitB == 0)
737 {
738 LOG_INFO("misc", "HandlePlayerLoginOpcode B");
739 break;
740 }
741 sess->HandleMoveWorldportAck();
742 }
743 while (sess->GetPlayer() && sess->GetPlayer()->IsInWorld() && sess->GetPlayer()->IsBeingTeleportedNear())
744 {
745 if (limitC == 0 || --limitC == 0)
746 {
747 LOG_INFO("misc", "HandlePlayerLoginOpcode C");
748 break;
749 }
750
751 Player* plMover = sess->GetPlayer()->m_mover->ToPlayer();
752 if (!plMover)
753 break;
754
756 pkt << plMover->GetPackGUID();
757 pkt << uint32(0); // flags
758 pkt << uint32(0); // time
759 sess->HandleMoveTeleportAck(pkt);
760 }
761 }
762 if (!p->FindMap() || !p->IsInWorld() || sess->IsKicked())
763 {
764 SendCharLogin(CHAR_LOGIN_DUPLICATE_CHARACTER);
765 return;
766 }
767
768 sess->SetPlayer(nullptr);
769 SetPlayer(p);
770 p->SetSession(this);
771 delete p->PlayerTalkClass;
774 return;
775 }
776 }
777
778 std::shared_ptr<LoginQueryHolder> holder = std::make_shared<LoginQueryHolder>(GetAccountId(), playerGuid);
779 if (!holder->Initialize())
780 {
781 m_playerLoading = false;
782 return;
783 }
784
785 AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(holder)).AfterComplete([this](SQLQueryHolderBase const& holder)
786 {
787 HandlePlayerLoginFromDB(static_cast<LoginQueryHolder const&>(holder));
788 });
789}
@ CONFIG_ENABLE_LOGIN_AFTER_DC
Definition: IWorld.h:145
@ CONFIG_REALM_LOGIN_ENABLED
Definition: IWorld.h:172
@ CHAR_LOGIN_DUPLICATE_CHARACTER
@ SMSG_CHARACTER_LOGIN_FAILED
Definition: Opcodes.h:95
@ MSG_MOVE_TELEPORT_ACK
Definition: Opcodes.h:229
void AfterComplete(std::function< void(SQLQueryHolderBase const &)> callback) &
Definition: QueryHolder.h:77
void SetSession(WorldSession *sess)
Definition: Player.h:1948
Player session in the World.
Definition: WorldSession.h:330
bool PlayerLoading() const
Definition: WorldSession.h:335
void HandlePlayerLoginToCharInWorld(Player *pCurrChar)
SQLQueryHolderCallback & AddQueryHolderCallback(SQLQueryHolderCallback &&callback)
void HandlePlayerLoginFromDB(LoginQueryHolder const &holder)

◆ HandlePlayerLoginToCharInWorld()

void WorldSession::HandlePlayerLoginToCharInWorld ( Player pCurrChar)

Definition at line 1123 of file CharacterHandler.cpp.

1124{
1125 ChatHandler chH = ChatHandler(this);
1126 m_playerLoading = true;
1127
1128 pCurrChar->SendDungeonDifficulty(false);
1129
1131 data << pCurrChar->GetMapId();
1132 data << pCurrChar->GetPositionX();
1133 data << pCurrChar->GetPositionY();
1134 data << pCurrChar->GetPositionZ();
1135 data << pCurrChar->GetOrientation();
1136 SendPacket(&data);
1137
1139
1140 data.Initialize(SMSG_FEATURE_SYSTEM_STATUS, 2); // added in 2.2.0
1141 data << uint8(2); // unknown value
1142 data << uint8(0); // enable(1)/disable(0) voice chat interface in client
1143 SendPacket(&data);
1144
1145 // Send MOTD
1146 {
1148
1149 // send server info
1150 if (sWorld->getIntConfig(CONFIG_ENABLE_SINFO_LOGIN) == 1)
1152
1153 LOG_DEBUG("network.opcode", "WORLD: Sent server info");
1154 }
1155
1156 data.Initialize(SMSG_LEARNED_DANCE_MOVES, 4 + 4);
1157 data << uint32(0);
1158 data << uint32(0);
1159 SendPacket(&data);
1160
1161 // Xinef: fix possible problem with flag UNIT_FLAG_STUNNED added during logout
1162 if (!pCurrChar->HasUnitState(UNIT_STATE_STUNNED))
1164
1166
1167 // necessary actions from AddPlayerToMap:
1168 pCurrChar->GetMap()->SendInitTransports(pCurrChar);
1169 pCurrChar->GetMap()->SendInitSelf(pCurrChar);
1170 pCurrChar->GetMap()->SendZoneDynamicInfo(pCurrChar);
1171 pCurrChar->m_clientGUIDs.clear();
1172 pCurrChar->UpdateObjectVisibility(false);
1173
1174 pCurrChar->CleanupChannels();
1176 uint32 currZone, currArea;
1177 pCurrChar->GetZoneAndAreaId(currZone, currArea);
1178 pCurrChar->SendInitWorldStates(currZone, currArea);
1179 pCurrChar->SetInGameTime(GameTime::GetGameTimeMS().count());
1180
1181 // Xinef: we need to resend all spell mods
1182 for (uint16 Opcode = SMSG_SET_FLAT_SPELL_MODIFIER; Opcode <= SMSG_SET_PCT_SPELL_MODIFIER; ++Opcode) // PCT = FLAT+1
1183 {
1185 for (uint32 opType = SPELLMOD_DAMAGE; opType < MAX_SPELLMOD; ++opType)
1186 {
1187 int32 i = 0;
1188 flag96 _mask = 0;
1189 SpellModList const& spellMods = pCurrChar->GetSpellModList(opType);
1190 if (spellMods.empty())
1191 continue;
1192
1193 for (int32 eff = 0; eff < 96; ++eff)
1194 {
1195 if (eff != 0 && eff % 32 == 0)
1196 _mask[i++] = 0;
1197
1198 _mask[i] = uint32(1) << (eff - (32 * i));
1199 int32 val = 0;
1200 for (auto const& spellMod : spellMods)
1201 if (spellMod->type == modType && spellMod->mask & _mask)
1202 val += spellMod->value;
1203
1204 if (val == 0)
1205 continue;
1206
1207 WorldPacket data(Opcode, (1 + 1 + 4));
1208 data << uint8(eff);
1209 data << uint8(opType);
1210 data << int32(val);
1211 SendPacket(&data);
1212 }
1213 }
1214 }
1215
1216 if (Group* group = pCurrChar->GetGroup())
1217 group->SendUpdate();
1218
1219 // pussywizard: send instance welcome message as when entering the instance through a portal
1220 if (MapDifficulty const* mapDiff = GetMapDifficultyData(pCurrChar->GetMap()->GetId(), pCurrChar->GetMap()->GetDifficulty()))
1221 if (mapDiff->resetTime)
1222 if (time_t timeReset = sInstanceSaveMgr->GetResetTimeFor(pCurrChar->GetMap()->GetId(), pCurrChar->GetMap()->GetDifficulty()))
1223 {
1224 uint32 timeleft = uint32(timeReset - GameTime::GetGameTime().count());
1225 GetPlayer()->SendInstanceResetWarning(pCurrChar->GetMap()->GetId(), pCurrChar->GetMap()->GetDifficulty(), timeleft, true);
1226 }
1227
1228 // this shouldn't do anything, becaues offline can't be on taxi, but just in case
1229 pCurrChar->ContinueTaxiFlight();
1230
1231 // send pet data, action bar, talents, etc.
1232 pCurrChar->PetSpellInitialize();
1233 pCurrChar->SendTalentsInfoData(true);
1234
1235 // show time before shutdown if shutdown planned.
1236 if (sWorld->IsShuttingDown())
1237 sWorld->ShutdownMsg(true, pCurrChar);
1238
1239 if (pCurrChar->IsGameMaster())
1241
1242 m_playerLoading = false;
1243}
std::list< SpellModifier * > SpellModList
Definition: Player.h:195
@ SPELLMOD_FLAT
Definition: Player.h:94
@ SPELLMOD_PCT
Definition: Player.h:95
@ SPELLMOD_DAMAGE
Definition: SpellDefines.h:77
#define MAX_SPELLMOD
Definition: SpellDefines.h:110
@ SMSG_SET_FLAT_SPELL_MODIFIER
Definition: Opcodes.h:644
@ SMSG_SET_PCT_SPELL_MODIFIER
Definition: Opcodes.h:645
Definition: Util.h:446
void CleanupChannels()
Definition: Player.cpp:4888
SpellModList const & GetSpellModList(uint32 type) const
Definition: Player.h:2557
void PetSpellInitialize()
Definition: Player.cpp:9331
GuidUnorderedSet m_clientGUIDs
Definition: Player.h:2330
void SendInitWorldStates(uint32 zone, uint32 area)
Definition: Player.cpp:8044
void UpdateObjectVisibility(bool forced=true, bool fromUpdate=false) override
void SendZoneDynamicInfo(Player *player)
Definition: Map.cpp:3683
void SendInitSelf(Player *player)
Definition: Map.cpp:2524
void SendInitTransports(Player *player)
Definition: Map.cpp:2548

◆ HandlePlayerLoginToCharOutOfWorld()

void WorldSession::HandlePlayerLoginToCharOutOfWorld ( Player pCurrChar)

Definition at line 1245 of file CharacterHandler.cpp.

1246{
1247 ABORT();
1248}
#define ABORT
Definition: Errors.h:76

◆ HandlePlayerLogoutOpcode()

void WorldSession::HandlePlayerLogoutOpcode ( WorldPackets::Character::PlayerLogout playerLogout)

Definition at line 478 of file MiscHandler.cpp.

479{
480}

◆ HandlePushQuestToParty()

void WorldSession::HandlePushQuestToParty ( WorldPacket recvPacket)

Definition at line 541 of file QuestHandler.cpp.

542{
543 uint32 questId;
544 recvPacket >> questId;
545
546 if (!_player->CanShareQuest(questId))
547 return;
548
549 LOG_DEBUG("network", "WORLD: Received CMSG_PUSHQUESTTOPARTY quest = {}", questId);
550
551 if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
552 {
553 if (Group* group = _player->GetGroup())
554 {
555 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
556 {
557 Player* player = itr->GetSource();
558
559 if (!player || player == _player || !player->IsInMap(_player)) // skip self
560 continue;
561
562 if (!player->SatisfyQuestStatus(quest, false))
563 {
565 continue;
566 }
567
568 if (player->GetQuestStatus(questId) == QUEST_STATUS_COMPLETE)
569 {
571 continue;
572 }
573
574 if (!player->CanTakeQuest(quest, false))
575 {
577 continue;
578 }
579
580 if (!player->SatisfyQuestLog(false))
581 {
583 continue;
584 }
585
586 // Check if Quest Share in BG is enabled
588 {
589 // Check if player is in BG
590 if (_player->InBattleground())
591 {
593 continue;
594 }
595 }
596
597 if (player->GetDivider())
598 {
600 continue;
601 }
602
604
605 if (quest->IsAutoAccept() && player->CanAddQuest(quest, true) && player->CanTakeQuest(quest, true))
606 player->AddQuestAndCheckCompletion(quest, _player);
607
608 if (quest->IsAutoComplete() || !quest->GetQuestMethod())
610 else
611 {
612 player->SetDivider(_player->GetGUID());
613 player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, player->GetGUID(), true);
614 }
615 }
616 }
617 }
618}
@ LANG_BG_SHARE_QUEST_ERROR
Definition: Language.h:1325
@ QUEST_STATUS_COMPLETE
Definition: QuestDef.h:101
@ QUEST_PARTY_MSG_FINISH_QUEST
Definition: QuestDef.h:73
@ QUEST_PARTY_MSG_CANT_TAKE_QUEST
Definition: QuestDef.h:67
@ QUEST_PARTY_MSG_BUSY
Definition: QuestDef.h:70
@ QUEST_PARTY_MSG_HAVE_QUEST
Definition: QuestDef.h:72
@ QUEST_PARTY_MSG_SHARING_QUEST
Definition: QuestDef.h:66
@ QUEST_PARTY_MSG_LOG_FULL
Definition: QuestDef.h:71
@ CONFIG_BATTLEGROUND_DISABLE_QUEST_SHARE_IN_BG
Definition: IWorld.h:113
void SendQuestGiverQuestDetails(Quest const *quest, ObjectGuid npcGUID, bool activateAccept) const
Definition: GossipDef.cpp:385
void SendQuestGiverRequestItems(Quest const *quest, ObjectGuid npcGUID, bool canComplete, bool closeOnCancel) const
Definition: GossipDef.cpp:713
bool IsInMap(WorldObject const *obj) const
Definition: Object.cpp:1285
bool CanTakeQuest(Quest const *quest, bool msg)
bool CanAddQuest(Quest const *quest, bool msg)
ObjectGuid GetDivider()
Definition: Player.h:1513
void SendPushToPartyResponse(Player const *player, uint8 msg) const
bool SatisfyQuestLog(bool msg)
void AddQuestAndCheckCompletion(Quest const *quest, Object *questGiver)
bool CanCompleteRepeatableQuest(Quest const *quest)
bool CanShareQuest(uint32 quest_id) const
void SetDivider(ObjectGuid guid=ObjectGuid::Empty)
Definition: Player.h:1514
bool SatisfyQuestStatus(Quest const *qInfo, bool msg) const

◆ HandlePVPLogDataOpcode()

void WorldSession::HandlePVPLogDataOpcode ( WorldPacket recvData)

Definition at line 346 of file BattleGroundHandler.cpp.

347{
348 LOG_DEBUG("network", "WORLD: Recvd MSG_PVP_LOG_DATA Message");
349
351 if (!bg)
352 return;
353
354 // Prevent players from sending BuildPvpLogDataPacket in an arena except for when sent in BattleGround::EndBattleGround.
355 if (bg->isArena())
356 return;
357
358 WorldPacket data;
359 bg->BuildPvPLogDataPacket(data);
360 SendPacket(&data);
361
362 LOG_DEBUG("network", "WORLD: Sent MSG_PVP_LOG_DATA Message");
363}
bool isArena() const
Definition: Battleground.h:388
void BuildPvPLogDataPacket(WorldPacket &data)

◆ HandleQueryGuildBankTabText()

void WorldSession::HandleQueryGuildBankTabText ( WorldPackets::Guild::GuildBankTextQuery packet)

Definition at line 391 of file GuildHandler.cpp.

392{
393 LOG_DEBUG("guild", "MSG_QUERY_GUILD_BANK_TEXT [{}]: TabId: {}", GetPlayerInfo(), packet.Tab);
394
395 if (Guild* guild = GetPlayer()->GetGuild())
396 guild->SendBankTabText(this, packet.Tab);
397}

◆ HandleQueryInspectAchievements()

void WorldSession::HandleQueryInspectAchievements ( WorldPacket recvData)

Definition at line 1604 of file MiscHandler.cpp.

1605{
1606 ObjectGuid guid;
1607 recv_data >> guid.ReadAsPacked();
1608
1609 Player* player = ObjectAccessor::GetPlayer(*_player, guid);
1610 if (!player)
1611 return;
1612
1614}
void SendRespondInspectAchievements(Player *player) const
Definition: Player.cpp:13601

◆ HandleQueryNextMailTime()

void WorldSession::HandleQueryNextMailTime ( WorldPacket recvData)

Definition at line 796 of file MailHandler.cpp.

797{
799
800 if (_player->unReadMails > 0)
801 {
802 data << float(0); // float
803 data << uint32(0); // count
804
805 uint32 count = 0;
806 time_t now = GameTime::GetGameTime().count();
807 std::set<uint32> sentSenders;
808 for (Mail const* mail : _player->GetMails())
809 {
810 // must be not checked yet
811 if (mail->checked & MAIL_CHECK_MASK_READ)
812 continue;
813
814 // and already delivered or expired
815 if (now < mail->deliver_time || now > mail->expire_time)
816 continue;
817
818 // only send each mail sender once
819 if (sentSenders.count(mail->sender))
820 continue;
821
822 data << (mail->messageType == MAIL_NORMAL ? ObjectGuid::Create<HighGuid::Player>(mail->sender) : ObjectGuid::Empty); // player guid
823 data << uint32(mail->messageType != MAIL_NORMAL ? mail->sender : 0); // non-player entries
824 data << uint32(mail->messageType);
825 data << uint32(mail->stationery);
826 data << float(mail->deliver_time - now);
827
828 sentSenders.insert(mail->sender);
829 ++count;
830 if (count == 2) // do not display more than 2 mails
831 break;
832 }
833
834 data.put<uint32>(4, count);
835 }
836 else
837 {
838 data << float(-DAY);
839 data << uint32(0);
840 }
841
842 SendPacket(&data);
843}
@ MSG_QUERY_NEXT_MAIL_TIME
Definition: Opcodes.h:674

◆ HandleQueryQuestsCompleted()

void WorldSession::HandleQueryQuestsCompleted ( WorldPacket recvData)

Definition at line 649 of file QuestHandler.cpp.

650{
651 size_t rew_count = _player->GetRewardedQuestCount();
652
653 WorldPacket data(SMSG_QUERY_QUESTS_COMPLETED_RESPONSE, 4 + 4 * rew_count);
654 data << uint32(rew_count);
655
656 const RewardedQuestSet& rewQuests = _player->getRewardedQuests();
657 for (RewardedQuestSet::const_iterator itr = rewQuests.begin(); itr != rewQuests.end(); ++itr)
658 data << uint32(*itr);
659
660 SendPacket(&data);
661}
std::unordered_set< uint32 > RewardedQuestSet
Definition: Player.h:616
@ SMSG_QUERY_QUESTS_COMPLETED_RESPONSE
Definition: Opcodes.h:1311
RewardedQuestSet const & getRewardedQuests() const
Definition: Player.h:1584
size_t GetRewardedQuestCount() const
Definition: Player.h:1588

◆ HandleQueryTimeOpcode()

void WorldSession::HandleQueryTimeOpcode ( WorldPacket recvPacket)

Definition at line 78 of file QueryHandler.cpp.

79{
81}

◆ HandleQuestConfirmAccept()

void WorldSession::HandleQuestConfirmAccept ( WorldPacket recvData)

Definition at line 454 of file QuestHandler.cpp.

455{
456 uint32 questId;
457 recvData >> questId;
458
459 LOG_DEBUG("network", "WORLD: Received CMSG_QUEST_CONFIRM_ACCEPT quest = {}", questId);
460
461 if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
462 {
463 if (!quest->HasFlag(QUEST_FLAGS_PARTY_ACCEPT))
464 return;
465
467 if (!originalPlayer)
468 return;
469
470 if (!_player->IsInSameRaidWith(originalPlayer) || !_player->IsAtGroupRewardDistance(originalPlayer))
471 return;
472
473 if (!_player->CanTakeQuest(quest, true) || _player->HasPendingBind())
474 return;
475
476 // pussywizard: exploit fix, can't share quests that give items to be sold
477 if (uint32 itemId = quest->GetSrcItemId())
478 if (ItemTemplate const* srcItem = sObjectMgr->GetItemTemplate(itemId))
479 if (srcItem->SellPrice > 0)
480 return;
481
482 if (_player->CanAddQuest(quest, true))
483 _player->AddQuestAndCheckCompletion(quest, nullptr); // nullptr, this prevent DB script from duplicate running
484
486 }
487}
@ QUEST_FLAGS_PARTY_ACCEPT
Definition: QuestDef.h:133
bool IsInSameRaidWith(Player const *p) const
Definition: Player.h:1835
bool IsAtGroupRewardDistance(WorldObject const *pRewardSource) const
Definition: Player.cpp:12471

◆ HandleQuestgiverAcceptQuestOpcode()

void WorldSession::HandleQuestgiverAcceptQuestOpcode ( WorldPacket recvPacket)

Definition at line 113 of file QuestHandler.cpp.

114{
115 ObjectGuid guid;
116 uint32 questId;
117 uint32 unk1;
118 recvData >> guid >> questId >> unk1;
119
120 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_ACCEPT_QUEST npc {}, quest = {}, unk1 = {}", guid.ToString(), questId, unk1);
121
123
124 // no or incorrect quest giver
125 if (!object || object == _player || (object->GetTypeId() != TYPEID_PLAYER && !object->hasQuest(questId)) ||
126 (object->GetTypeId() == TYPEID_PLAYER && !object->ToPlayer()->CanShareQuest(questId)))
127 {
130 return;
131 }
132
133 // some kind of WPE protection
135 return;
136
137 if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
138 {
139 // pussywizard: exploit fix, can't share quests that give items to be sold
140 if (object->GetTypeId() == TYPEID_PLAYER)
141 if (uint32 itemId = quest->GetSrcItemId())
142 if (ItemTemplate const* srcItem = sObjectMgr->GetItemTemplate(itemId))
143 if (srcItem->SellPrice > 0)
144 return;
145
146 // prevent cheating
147 if (!GetPlayer()->CanTakeQuest(quest, true))
148 {
151 return;
152 }
153
154 if (_player->GetDivider())
155 {
157 if (player)
158 {
161 }
162 }
163
164 if (_player->CanAddQuest(quest, true))
165 {
166 _player->AddQuestAndCheckCompletion(quest, object);
167
168 if (quest->HasFlag(QUEST_FLAGS_PARTY_ACCEPT))
169 {
170 if (Group* group = _player->GetGroup())
171 {
172 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
173 {
174 Player* itrPlayer = itr->GetSource();
175 if (!itrPlayer || itrPlayer == _player || !itrPlayer->IsAtGroupRewardDistance(_player) || itrPlayer->HasPendingBind()) // xinef: check range
176 continue;
177
178 if (itrPlayer->CanTakeQuest(quest, false))
179 {
180 itrPlayer->SetDivider(_player->GetGUID());
181
182 // need confirmation that any gossip window will close
183 itrPlayer->PlayerTalkClass->SendCloseGossip();
184
185 _player->SendQuestConfirmAccept(quest, itrPlayer);
186 }
187 }
188 }
189 }
190
192
193 if (quest->GetSrcSpell() > 0)
194 _player->CastSpell(_player, quest->GetSrcSpell(), true);
195
196 return;
197 }
198 }
199
201}
@ TYPEMASK_ITEM
Definition: ObjectGuid.h:49
@ TYPEMASK_UNIT
Definition: ObjectGuid.h:51
@ TYPEMASK_GAMEOBJECT
Definition: ObjectGuid.h:53
@ TYPEMASK_PLAYER
Definition: ObjectGuid.h:52
@ QUEST_PARTY_MSG_ACCEPT_QUEST
Definition: QuestDef.h:68
Object * GetObjectByTypeMask(WorldObject const &, ObjectGuid const guid, uint32 typemask)
Definition: Object.h:97
virtual bool hasQuest(uint32) const
Definition: Object.h:183
void SendQuestConfirmAccept(Quest const *quest, Player *pReceiver)
bool CanInteractWithQuestGiver(Object *questGiver)
Definition: Player.cpp:2022

◆ HandleQuestgiverCancel()

void WorldSession::HandleQuestgiverCancel ( WorldPacket recvData)

Definition at line 381 of file QuestHandler.cpp.

382{
383 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_CANCEL");
384
386}

◆ HandleQuestgiverChooseRewardOpcode()

void WorldSession::HandleQuestgiverChooseRewardOpcode ( WorldPacket recvPacket)

Definition at line 250 of file QuestHandler.cpp.

251{
252 uint32 questId, reward;
253 ObjectGuid guid;
254 recvData >> guid >> questId >> reward;
255
256 if (reward >= QUEST_REWARD_CHOICES_COUNT)
257 {
258 LOG_ERROR("network.opcode", "Error in CMSG_QUESTGIVER_CHOOSE_REWARD: player {} ({}) tried to get invalid reward ({}) (probably packet hacking)",
259 _player->GetName(), _player->GetGUID().ToString(), reward);
260 return;
261 }
262
263 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_CHOOSE_REWARD npc {}, quest = {}, reward = {}", guid.ToString(), questId, reward);
264
266 if (!object || !object->hasInvolvedQuest(questId))
267 return;
268
269 // some kind of WPE protection
271 return;
272
273 if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
274 {
275 if ((!_player->CanSeeStartQuest(quest) && _player->GetQuestStatus(questId) == QUEST_STATUS_NONE) ||
276 (_player->GetQuestStatus(questId) != QUEST_STATUS_COMPLETE && !quest->IsAutoComplete() && quest->GetQuestMethod()))
277 {
278 LOG_ERROR("network.opcode", "HACK ALERT: Player {} ({}) is trying to complete quest (id: {}) but he has no right to do it!",
279 _player->GetName(), _player->GetGUID().ToString(), questId);
280 return;
281 }
282 if (_player->CanRewardQuest(quest, reward, true))
283 {
284 _player->RewardQuest(quest, reward, object);
285
286 // Special dialog status update (client does not query this)
287 if (!quest->GetQuestMethod())
288 {
290 }
291
292 switch (object->GetTypeId())
293 {
294 case TYPEID_UNIT:
295 {
296 Creature* questgiver = object->ToCreature();
297 if (!sScriptMgr->OnQuestReward(_player, questgiver, quest, reward))
298 {
299 // Send next quest
300 if (Quest const* nextQuest = _player->GetNextQuest(guid, quest))
301 {
302 if (_player->CanTakeQuest(nextQuest, false))
303 {
304 if (nextQuest->IsAutoAccept())
305 {
306 // QUEST_FLAGS_AUTO_ACCEPT was not used by Blizzard.
307 if (_player->CanAddQuest(nextQuest, false))
308 {
309 _player->AddQuestAndCheckCompletion(nextQuest, object);
310 }
311 else
312 {
313 // Auto accept is set for a custom quest and there is no inventory space
315 break;
316 }
317 }
318 _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, guid, true);
319 }
320 }
321
322 questgiver->AI()->sQuestReward(_player, quest, reward);
323 }
324 break;
325 }
327 {
328 GameObject* questGiver = object->ToGameObject();
329 if (!sScriptMgr->OnQuestReward(_player, questGiver, quest, reward))
330 {
331 // Send next quest
332 if (Quest const* nextQuest = _player->GetNextQuest(guid, quest))
333 {
334 if (_player->CanAddQuest(nextQuest, false) && _player->CanTakeQuest(nextQuest, false))
335 {
336 if (nextQuest->IsAutoAccept())
337 _player->AddQuestAndCheckCompletion(nextQuest, object);
338 _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, guid, true);
339 }
340 }
341
342 questGiver->AI()->QuestReward(_player, quest, reward);
343 }
344 break;
345 }
346 default:
347 break;
348 }
349 }
350 else
352 }
353}
@ TYPEID_GAMEOBJECT
Definition: ObjectGuid.h:39
@ QUEST_STATUS_NONE
Definition: QuestDef.h:100
#define QUEST_REWARD_CHOICES_COUNT
Definition: QuestDef.h:38
virtual bool QuestReward(Player *, Quest const *, uint32)
Definition: GameObjectAI.h:58
virtual void sQuestReward(Player *, Quest const *, uint32)
Definition: UnitAI.h:347
void SendQuestGiverStatus(uint8 questStatus, ObjectGuid npcGUID) const
Definition: GossipDef.cpp:375
void SendQuestGiverOfferReward(Quest const *quest, ObjectGuid npcGUID, bool enableNext) const
Definition: GossipDef.cpp:621
GameObject * ToGameObject()
Definition: Object.h:202
virtual bool hasInvolvedQuest(uint32) const
Definition: Object.h:184
QuestGiverStatus GetQuestDialogStatus(Object *questGiver)
bool CanSeeStartQuest(Quest const *quest)
Quest const * GetNextQuest(ObjectGuid guid, Quest const *quest)
void RewardQuest(Quest const *quest, uint32 reward, Object *questGiver, bool announce=true, bool isLFGReward=false)

◆ HandleQuestgiverCompleteQuest()

void WorldSession::HandleQuestgiverCompleteQuest ( WorldPacket recvData)

Definition at line 489 of file QuestHandler.cpp.

490{
491 uint32 questId;
492 ObjectGuid guid;
493
494 recvData >> guid >> questId;
495
496 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_COMPLETE_QUEST npc {}, quest = {}", guid.ToString(), questId);
497
499 if (!object || !object->hasInvolvedQuest(questId))
500 return;
501
502 // some kind of WPE protection
504 return;
505
506 if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
507 {
509 {
510 LOG_ERROR("network.opcode", "Possible hacking attempt: Player {} [{}] tried to complete quest [entry: {}] without being in possession of the quest!",
511 _player->GetName(), _player->GetGUID().ToString(), questId);
512 return;
513 }
514
516 if (bg->GetBgTypeID(true) == BATTLEGROUND_AV)
517 bg->ToBattlegroundAV()->HandleQuestComplete(questId, _player);
518
520 {
521 if (quest->IsRepeatable())
523 else
524 _player->PlayerTalkClass->SendQuestGiverRequestItems(quest, guid, _player->CanRewardQuest(quest, false), false);
525 }
526 else
527 {
528 if (quest->GetReqItemsCount()) // some items required
529 _player->PlayerTalkClass->SendQuestGiverRequestItems(quest, guid, _player->CanRewardQuest(quest, false), false);
530 else // no items required
532 }
533 }
534}
@ BATTLEGROUND_AV

◆ HandleQuestgiverHelloOpcode()

void WorldSession::HandleQuestgiverHelloOpcode ( WorldPacket recvPacket)

Definition at line 81 of file QuestHandler.cpp.

82{
83 ObjectGuid guid;
84 recvData >> guid;
85
86 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_HELLO npc {}", guid.ToString());
87
89 if (!creature)
90 {
91 LOG_DEBUG("network", "WORLD: HandleQuestgiverHelloOpcode - Unit ({}) not found or you can't interact with him.", guid.ToString());
92 return;
93 }
94
95 // remove fake death
96 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
98
99 // Stop the npc if moving
100 if (uint32 pause = creature->GetMovementTemplate().GetInteractionPauseTimer())
101 creature->PauseMovement(pause);
102 creature->SetHomePosition(creature->GetPosition());
103
104 if (sScriptMgr->OnGossipHello(_player, creature))
105 return;
106
107 _player->PrepareGossipMenu(creature, creature->GetCreatureTemplate()->GossipMenuId, true);
108 _player->SendPreparedGossip(creature);
109
110 creature->AI()->sGossipHello(_player);
111}

◆ HandleQuestgiverQueryQuestOpcode()

void WorldSession::HandleQuestgiverQueryQuestOpcode ( WorldPacket recvPacket)

Definition at line 203 of file QuestHandler.cpp.

204{
205 ObjectGuid guid;
206 uint32 questId;
207 uint8 unk1;
208 recvData >> guid >> questId >> unk1;
209 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_QUERY_QUEST npc {}, quest = {}, unk1 = {}", guid.ToString(), questId, unk1);
210
211 // Verify that the guid is valid and is a questgiver or involved in the requested quest
213 if (!object || (!object->hasQuest(questId) && !object->hasInvolvedQuest(questId)))
214 {
216 return;
217 }
218
219 if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
220 {
221 // not sure here what should happen to quests with QUEST_FLAGS_AUTOCOMPLETE
222 // if this breaks them, add && object->GetTypeId() == TYPEID_ITEM to this check
223 // item-started quests never have that flag
224 if (!_player->CanTakeQuest(quest, true))
225 return;
226
227 if (quest->IsAutoAccept() && _player->CanAddQuest(quest, true))
228 _player->AddQuestAndCheckCompletion(quest, object);
229
230 if (quest->IsAutoComplete() || !quest->GetQuestMethod())
231 _player->PlayerTalkClass->SendQuestGiverRequestItems(quest, object->GetGUID(), _player->CanCompleteQuest(quest->GetQuestId()), true);
232 else
234 }
235}
bool CanCompleteQuest(uint32 quest_id, const QuestStatusData *q_savedStatus=nullptr)

◆ HandleQuestgiverQuestAutoLaunch()

void WorldSession::HandleQuestgiverQuestAutoLaunch ( WorldPacket recvPacket)

Definition at line 536 of file QuestHandler.cpp.

537{
538 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_QUEST_AUTOLAUNCH");
539}

◆ HandleQuestgiverRequestRewardOpcode()

void WorldSession::HandleQuestgiverRequestRewardOpcode ( WorldPacket recvPacket)

Definition at line 355 of file QuestHandler.cpp.

356{
357 uint32 questId;
358 ObjectGuid guid;
359 recvData >> guid >> questId;
360
361 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_REQUEST_REWARD npc {}, quest = {}", guid.ToString(), questId);
362
364 if (!object || !object->hasInvolvedQuest(questId))
365 return;
366
367 // some kind of WPE protection
369 return;
370
371 if (_player->CanCompleteQuest(questId))
372 _player->CompleteQuest(questId);
373
375 return;
376
377 if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
379}
void CompleteQuest(uint32 quest_id)

◆ HandleQuestgiverStatusMultipleQuery()

void WorldSession::HandleQuestgiverStatusMultipleQuery ( WorldPacket recvPacket)

Definition at line 642 of file QuestHandler.cpp.

643{
644 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY");
645
647}

◆ HandleQuestgiverStatusQueryOpcode()

void WorldSession::HandleQuestgiverStatusQueryOpcode ( WorldPacket recvPacket)

Definition at line 34 of file QuestHandler.cpp.

35{
36 ObjectGuid guid;
37 recvData >> guid;
38 uint32 questStatus = DIALOG_STATUS_NONE;
39
41 // Did we already get a gossip menu with that NPC? if so no need to status query
42 if (gossipMenu.GetSenderGUID() == guid)
43 {
44 return;
45 }
46
48 if (!questGiver)
49 {
50 LOG_DEBUG("network.opcode", "Error in CMSG_QUESTGIVER_STATUS_QUERY, called for not found questgiver ({})", guid.ToString());
51 return;
52 }
53
54 switch (questGiver->GetTypeId())
55 {
56 case TYPEID_UNIT:
57 {
58 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for npc {}", guid.ToString());
59 if (!questGiver->ToCreature()->IsHostileTo(_player)) // do not show quest status to enemies
60 questStatus = _player->GetQuestDialogStatus(questGiver);
61 break;
62 }
64 {
65 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for GameObject {}", guid.ToString());
66 if (sWorld->getBoolConfig(CONFIG_OBJECT_QUEST_MARKERS))
67 {
68 questStatus = _player->GetQuestDialogStatus(questGiver);
69 }
70 break;
71 }
72 default:
73 LOG_ERROR("network.opcode", "QuestGiver called for unexpected type {}", questGiver->GetTypeId());
74 break;
75 }
76
77 // inform client about status of quest
79}
@ DIALOG_STATUS_NONE
Definition: QuestDef.h:112
@ CONFIG_OBJECT_QUEST_MARKERS
Definition: IWorld.h:179
bool IsHostileTo(Unit const *unit) const
Definition: Unit.cpp:10197

◆ HandleQuestLogRemoveQuest()

void WorldSession::HandleQuestLogRemoveQuest ( WorldPacket recvData)

Definition at line 401 of file QuestHandler.cpp.

402{
403 uint8 slot;
404 recvData >> slot;
405
406 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTLOG_REMOVE_QUEST slot = {}", slot);
407
408 if (slot < MAX_QUEST_LOG_SIZE)
409 {
410 if (uint32 questId = _player->GetQuestSlotQuestId(slot))
411 {
412 if (!_player->TakeQuestSourceItem(questId, true))
413 return; // can't un-equip some items, reject quest cancel
414
415 if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
416 {
417 if (quest->HasSpecialFlag(QUEST_SPECIAL_FLAGS_TIMED))
418 _player->RemoveTimedQuest(questId);
419
420 if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP))
421 {
424 }
425 }
426
427 _player->TakeQuestSourceItem(questId, true); // remove quest src item from player
428 _player->AbandonQuest(questId); // remove all quest items player received before abandoning quest.
429 _player->RemoveActiveQuest(questId);
431
432 sScriptMgr->OnQuestAbandon(_player, questId);
433
434 LOG_DEBUG("network.opcode", "Player {} abandoned quest {}", _player->GetGUID().ToString(), questId);
435 // check if Quest Tracker is enabled
436 if (sWorld->getBoolConfig(CONFIG_QUEST_ENABLE_QUEST_TRACKER))
437 {
438 // prepare Quest Tracker datas
439 auto stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_QUEST_TRACK_ABANDON_TIME);
440 stmt->SetData(0, questId);
441 stmt->SetData(1, _player->GetGUID().GetCounter());
442
443 // add to Quest Tracker
444 CharacterDatabase.Execute(stmt);
445 }
446 }
447
448 _player->SetQuestSlot(slot, 0);
449
451 }
452}
@ CHAR_UPD_QUEST_TRACK_ABANDON_TIME
@ QUEST_FLAGS_FLAGS_PVP
Definition: QuestDef.h:145
#define MAX_QUEST_LOG_SIZE
Definition: QuestDef.h:33
@ QUEST_SPECIAL_FLAGS_TIMED
Definition: QuestDef.h:175
@ CONFIG_QUEST_ENABLE_QUEST_TRACKER
Definition: IWorld.h:149
@ ACHIEVEMENT_TIMED_TYPE_QUEST
Definition: DBCEnums.h:117
@ ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED
Definition: DBCEnums.h:220
bool IsInHostileArea
Definition: Player.h:362
bool HasPvPForcingQuest() const
void UpdatePvPState()
uint32 GetQuestSlotQuestId(uint16 slot) const
Definition: Player.h:1449
void SetQuestSlot(uint16 slot, uint32 quest_id, uint32 timer=0)
Definition: Player.h:1453
bool TakeQuestSourceItem(uint32 questId, bool msg)
void RemoveActiveQuest(uint32 questId, bool update=true)
void RemoveTimedQuest(uint32 quest_id)
Definition: Player.h:1521
void RemoveTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry)
Definition: Player.cpp:13616
void AbandonQuest(uint32 quest_id)

◆ HandleQuestLogSwapQuest()

void WorldSession::HandleQuestLogSwapQuest ( WorldPacket recvData)

Definition at line 388 of file QuestHandler.cpp.

389{
390 uint8 slot1, slot2;
391 recvData >> slot1 >> slot2;
392
393 if (slot1 == slot2 || slot1 >= MAX_QUEST_LOG_SIZE || slot2 >= MAX_QUEST_LOG_SIZE)
394 return;
395
396 LOG_DEBUG("network", "WORLD: Received CMSG_QUESTLOG_SWAP_QUEST slot 1 = {}, slot 2 = {}", slot1, slot2);
397
398 GetPlayer()->SwapQuestSlot(slot1, slot2);
399}
void SwapQuestSlot(uint16 slot1, uint16 slot2)
Definition: Player.h:1471

◆ HandleQuestPOIQuery()

void WorldSession::HandleQuestPOIQuery ( WorldPacket recvData)

Definition at line 412 of file QueryHandler.cpp.

413{
414 uint32 count;
415 recvData >> count; // quest count, max=25
416
417 if (count > MAX_QUEST_LOG_SIZE)
418 {
419 recvData.rfinish();
420 return;
421 }
422
423 // Read quest ids and add the in a unordered_set so we don't send POIs for the same quest multiple times
424 std::unordered_set<uint32> questIds;
425 for (uint32 i = 0; i < count; ++i)
426 questIds.insert(recvData.read<uint32>()); // quest id
427
428 WorldPacket data(SMSG_QUEST_POI_QUERY_RESPONSE, 4 + (4 + 4)*questIds.size());
429 data << uint32(questIds.size()); // count
430
431 for (std::unordered_set<uint32>::const_iterator itr = questIds.begin(); itr != questIds.end(); ++itr)
432 {
433 uint32 questId = *itr;
434 bool questOk = false;
435
436 uint16 questSlot = _player->FindQuestSlot(questId);
437
438 if (questSlot != MAX_QUEST_LOG_SIZE)
439 questOk = _player->GetQuestSlotQuestId(questSlot) == questId;
440
441 if (questOk)
442 {
443 QuestPOIVector const* POI = sObjectMgr->GetQuestPOIVector(questId);
444
445 if (POI)
446 {
447 data << uint32(questId); // quest ID
448 data << uint32(POI->size()); // POI count
449
450 for (QuestPOIVector::const_iterator itr = POI->begin(); itr != POI->end(); ++itr)
451 {
452 data << uint32(itr->Id); // POI index
453 data << int32(itr->ObjectiveIndex); // objective index
454 data << uint32(itr->MapId); // mapid
455 data << uint32(itr->AreaId); // areaid
456 data << uint32(itr->FloorId); // floorid
457 data << uint32(itr->Unk3); // unknown
458 data << uint32(itr->Unk4); // unknown
459 data << uint32(itr->points.size()); // POI points count
460
461 for (std::vector<QuestPOIPoint>::const_iterator itr2 = itr->points.begin(); itr2 != itr->points.end(); ++itr2)
462 {
463 data << int32(itr2->x); // POI point x
464 data << int32(itr2->y); // POI point y
465 }
466 }
467 }
468 else
469 {
470 data << uint32(questId); // quest ID
471 data << uint32(0); // POI count
472 }
473 }
474 else
475 {
476 data << uint32(questId); // quest ID
477 data << uint32(0); // POI count
478 }
479 }
480
481 SendPacket(&data);
482}
std::vector< QuestPOI > QuestPOIVector
Definition: ObjectMgr.h:666
@ SMSG_QUEST_POI_QUERY_RESPONSE
Definition: Opcodes.h:514
uint16 FindQuestSlot(uint32 quest_id) const

◆ HandleQuestPushResult()

void WorldSession::HandleQuestPushResult ( WorldPacket recvPacket)

Definition at line 620 of file QuestHandler.cpp.

621{
622 ObjectGuid guid;
623 uint32 questId;
624 uint8 msg;
625 recvPacket >> guid >> questId >> msg;
626
627 LOG_DEBUG("network", "WORLD: Received MSG_QUEST_PUSH_RESULT");
628
629 if (_player->GetDivider() && _player->GetDivider() == guid)
630 {
632 {
633 WorldPacket data(MSG_QUEST_PUSH_RESULT, 8 + 4 + 1);
634 data << _player->GetGUID();
635 data << uint8(msg); // valid values: 0-8
636 player->GetSession()->SendPacket(&data);
638 }
639 }
640}
@ MSG_QUEST_PUSH_RESULT
Definition: Opcodes.h:660

◆ HandleQuestQueryOpcode()

void WorldSession::HandleQuestQueryOpcode ( WorldPacket recvPacket)

Definition at line 237 of file QuestHandler.cpp.

238{
239 if (!_player)
240 return;
241
242 uint32 questId;
243 recvData >> questId;
244 LOG_DEBUG("network", "WORLD: Received CMSG_QUEST_QUERY quest = {}", questId);
245
246 if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
248}
void SendQuestQueryResponse(Quest const *quest) const
Definition: GossipDef.cpp:490

◆ HandleRaidReadyCheckFinishedOpcode()

void WorldSession::HandleRaidReadyCheckFinishedOpcode ( WorldPacket recvData)

Definition at line 779 of file GroupHandler.cpp.

780{
781 //Group* group = GetPlayer()->GetGroup();
782 //if (!group)
783 // return;
784
785 //if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
786 // return;
787
788 // Is any reaction need?
789}

◆ HandleRaidReadyCheckOpcode()

void WorldSession::HandleRaidReadyCheckOpcode ( WorldPacket recvData)

error handling

Definition at line 733 of file GroupHandler.cpp.

734{
735 LOG_DEBUG("network", "WORLD: Received MSG_RAID_READY_CHECK");
736
737 Group* group = GetPlayer()->GetGroup();
738 if (!group)
739 return;
740
741 if (recvData.empty()) // request
742 {
744 if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
745 return;
746 /********************/
747
748 // Check if Ready Check in BG is enabled
750 {
751 // Check if player is in BG
752 if (_player->InBattleground())
753 {
755 return;
756 }
757 }
758
759 // everything's fine, do it
761 data << GetPlayer()->GetGUID();
762 group->BroadcastPacket(&data, false, -1);
763
764 group->OfflineReadyCheck();
765 }
766 else // answer
767 {
768 uint8 state;
769 recvData >> state;
770
771 // everything's fine, do it
773 data << GetPlayer()->GetGUID();
774 data << uint8(state);
775 group->BroadcastReadyCheck(&data);
776 }
777}
@ LANG_BG_READY_CHECK_ERROR
Definition: Language.h:1326
@ CONFIG_BATTLEGROUND_DISABLE_READY_CHECK_IN_BG
Definition: IWorld.h:114
@ MSG_RAID_READY_CHECK
Definition: Opcodes.h:832
@ MSG_RAID_READY_CHECK_CONFIRM
Definition: Opcodes.h:972
void BroadcastReadyCheck(WorldPacket const *packet)
Definition: Group.cpp:1739
void OfflineReadyCheck()
Definition: Group.cpp:1750
bool empty() const
Definition: ByteBuffer.h:445

◆ HandleRaidTargetUpdateOpcode()

void WorldSession::HandleRaidTargetUpdateOpcode ( WorldPacket recvData)

error handling

Definition at line 573 of file GroupHandler.cpp.

574{
575 LOG_DEBUG("network", "WORLD: Received MSG_RAID_TARGET_UPDATE");
576
577 Group* group = GetPlayer()->GetGroup();
578 if (!group)
579 return;
580
581 uint8 x;
582 recvData >> x;
583
585 /********************/
586
587 // everything's fine, do it
588 if (x == 0xFF) // target icon request
589 {
590 group->SendTargetIconList(this);
591 }
592 else // target icon update
593 {
594 if (group->isRaidGroup() && !group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
595 return;
596
597 ObjectGuid guid;
598 recvData >> guid;
599
600 if (guid.IsPlayer())
601 {
603
604 if (!target || target->IsHostileTo(GetPlayer()))
605 return;
606 }
607
608 group->SetTargetIcon(x, _player->GetGUID(), guid);
609 }
610}
void SendTargetIconList(WorldSession *session)
Definition: Group.cpp:1613
void SetTargetIcon(uint8 id, ObjectGuid whoGuid, ObjectGuid targetGuid)
Definition: Group.cpp:1592

◆ HandleRandomRollOpcode()

void WorldSession::HandleRandomRollOpcode ( WorldPackets::Misc::RandomRollClient packet)

Definition at line 564 of file GroupHandler.cpp.

565{
566 uint32 minimum, maximum;
567 minimum = packet.Min;
568 maximum = packet.Max;
569
570 GetPlayer()->DoRandomRoll(minimum, maximum);
571}
uint32 DoRandomRoll(uint32 minimum, uint32 maximum)
Definition: Player.cpp:15866

◆ HandleReadItem()

void WorldSession::HandleReadItem ( WorldPacket recvPacket)

Definition at line 695 of file ItemHandler.cpp.

696{
697 //LOG_DEBUG("network.opcode", "WORLD: CMSG_READ_ITEM");
698
699 uint8 bag, slot;
700 recvData >> bag >> slot;
701
702 //LOG_DEBUG("network.opcode", "STORAGE: Read bag = {}, slot = {}", bag, slot);
703 Item* pItem = _player->GetItemByPos(bag, slot);
704
705 if (pItem && pItem->GetTemplate()->PageText)
706 {
707 WorldPacket data;
708
709 InventoryResult msg = _player->CanUseItem(pItem);
710 if (msg == EQUIP_ERR_OK)
711 {
713 LOG_DEBUG("network.opcode", "STORAGE: Item page sent");
714 }
715 else
716 {
718 LOG_DEBUG("network.opcode", "STORAGE: Unable to read item");
719 _player->SendEquipError(msg, pItem, nullptr);
720 }
721 data << pItem->GetGUID();
722 SendPacket(&data);
723 }
724 else
726}
@ SMSG_READ_ITEM_FAILED
Definition: Opcodes.h:205
@ SMSG_READ_ITEM_OK
Definition: Opcodes.h:204
InventoryResult CanUseItem(Item *pItem, bool not_loading=true) const

◆ HandleReadyForAccountDataTimes()

void WorldSession::HandleReadyForAccountDataTimes ( WorldPacket recvData)

Definition at line 1626 of file MiscHandler.cpp.

1627{
1628 // empty opcode
1629 LOG_DEBUG("network", "WORLD: CMSG_READY_FOR_ACCOUNT_DATA_TIMES");
1630
1632}
#define GLOBAL_CACHE_MASK
Definition: WorldSession.h:178

◆ HandleRealmSplitOpcode()

void WorldSession::HandleRealmSplitOpcode ( WorldPacket recvData)

Definition at line 1220 of file MiscHandler.cpp.

1221{
1222 LOG_DEBUG("network", "CMSG_REALM_SPLIT");
1223
1224 uint32 unk;
1225 std::string split_date = "01/01/01";
1226 recv_data >> unk;
1227
1228 WorldPacket data(SMSG_REALM_SPLIT, 4 + 4 + split_date.size() + 1);
1229 data << unk;
1230 data << uint32(0x00000000); // realm split state
1231 // split states:
1232 // 0x0 realm normal
1233 // 0x1 realm split
1234 // 0x2 realm split pending
1235 data << split_date;
1236 SendPacket(&data);
1237}
@ SMSG_REALM_SPLIT
Definition: Opcodes.h:937

◆ HandleReclaimCorpseOpcode()

void WorldSession::HandleReclaimCorpseOpcode ( WorldPacket recvPacket)

Definition at line 649 of file MiscHandler.cpp.

650{
651 LOG_DEBUG("network", "WORLD: Received CMSG_RECLAIM_CORPSE");
652
653 ObjectGuid guid;
654 recv_data >> guid;
655
656 if (_player->IsAlive())
657 return;
658
659 // do not allow corpse reclaim in arena
660 if (_player->InArena())
661 return;
662
663 // body not released yet
665 return;
666
667 Corpse* corpse = _player->GetCorpse();
668 if (!corpse)
669 return;
670
671 // prevent resurrect before 30-sec delay after body release not finished
672 if (time_t(corpse->GetGhostTime() + _player->GetCorpseReclaimDelay(corpse->GetType() == CORPSE_RESURRECTABLE_PVP)) > time_t(GameTime::GetGameTime().count()))
673 return;
674
676 return;
677
678 // resurrect
680
681 // spawn bones
683}
#define CORPSE_RECLAIM_RADIUS
Definition: Corpse.h:35
@ CORPSE_RESURRECTABLE_PVP
Definition: Corpse.h:30
time_t const & GetGhostTime() const
Definition: Corpse.h:70
Corpse * GetCorpse() const
Definition: Player.cpp:4591
uint32 GetCorpseReclaimDelay(bool pvp) const
Definition: Player.cpp:12628
bool InArena() const
Definition: Player.cpp:12014

◆ HandleRemoveGlyph()

void WorldSession::HandleRemoveGlyph ( WorldPacket recvData)

Definition at line 1575 of file CharacterHandler.cpp.

1576{
1577 uint32 slot;
1578 recvData >> slot;
1579
1580 if (slot >= MAX_GLYPH_SLOT_INDEX)
1581 {
1582 LOG_DEBUG("network", "Client sent wrong glyph slot number in opcode CMSG_REMOVE_GLYPH {}", slot);
1583 return;
1584 }
1585
1586 if (uint32 glyph = _player->GetGlyph(slot))
1587 {
1588 if (GlyphPropertiesEntry const* glyphEntry = sGlyphPropertiesStore.LookupEntry(glyph))
1589 {
1590 _player->RemoveAurasDueToSpell(glyphEntry->SpellId);
1591
1592 // Removed any triggered auras
1593 Unit::AuraMap& ownedAuras = _player->GetOwnedAuras();
1594 for (Unit::AuraMap::iterator iter = ownedAuras.begin(); iter != ownedAuras.end();)
1595 {
1596 Aura* aura = iter->second;
1597 if (SpellInfo const* triggeredByAuraSpellInfo = aura->GetTriggeredByAuraSpellInfo())
1598 {
1599 if (triggeredByAuraSpellInfo->Id == glyphEntry->SpellId)
1600 {
1601 _player->RemoveOwnedAura(iter);
1602 continue;
1603 }
1604 }
1605 ++iter;
1606 }
1607
1608 _player->SendLearnPacket(glyphEntry->SpellId, false); // Send packet to properly handle client-side spell tooltips
1609 _player->SetGlyph(slot, 0, true);
1611 }
1612 }
1613}
DBCStorage< GlyphPropertiesEntry > sGlyphPropertiesStore(GlyphPropertiesfmt)
#define MAX_GLYPH_SLOT_INDEX
void SendLearnPacket(uint32 spellId, bool learn)
Definition: Player.cpp:2970
uint32 GetGlyph(uint8 slot) const
Definition: Player.h:1720
void SetGlyph(uint8 slot, uint32 glyph, bool save)
Definition: Player.h:1712
std::multimap< uint32, Aura * > AuraMap
Definition: Unit.h:1295
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:4823
AuraMap & GetOwnedAuras()
Definition: Unit.h:1911
SpellInfo const * GetTriggeredByAuraSpellInfo() const

◆ HandleRepairItemOpcode()

void WorldSession::HandleRepairItemOpcode ( WorldPacket recvPacket)

Definition at line 891 of file NPCHandler.cpp.

892{
893 LOG_DEBUG("network", "WORLD: CMSG_REPAIR_ITEM");
894
895 ObjectGuid npcGUID, itemGUID;
896 uint8 guildBank; // new in 2.3.2, bool that means from guild bank money
897
898 recvData >> npcGUID >> itemGUID >> guildBank;
899
901 if (!unit)
902 {
903 LOG_DEBUG("network", "WORLD: HandleRepairItemOpcode - Unit ({}) not found or you can not interact with him.", npcGUID.ToString());
904 return;
905 }
906
907 // remove fake death
908 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
910
911 // reputation discount
912 float discountMod = _player->GetReputationPriceDiscount(unit);
913
914 sScriptMgr->OnBeforePlayerDurabilityRepair(_player, npcGUID, itemGUID, discountMod, guildBank);
915
916 if (itemGUID)
917 {
918 LOG_DEBUG("network", "ITEM: Repair item, item {}, npc {}", itemGUID.ToString(), npcGUID.ToString());
919
920 Item* item = _player->GetItemByGuid(itemGUID);
921 if (item)
922 _player->DurabilityRepair(item->GetPos(), true, discountMod, guildBank);
923 }
924 else
925 {
926 LOG_DEBUG("network", "ITEM: Repair all items, npc {}", npcGUID.ToString());
927 _player->DurabilityRepairAll(true, discountMod, guildBank);
928 }
929}
@ UNIT_NPC_FLAG_REPAIR
Definition: Unit.h:528
float GetReputationPriceDiscount(Creature const *creature) const
Definition: Player.cpp:12053
uint32 DurabilityRepairAll(bool cost, float discountMod, bool guildBank)
Definition: Player.cpp:4709
uint32 DurabilityRepair(uint16 pos, bool cost, float discountMod, bool guildBank)
Definition: Player.cpp:4725

◆ HandleRepopRequestOpcode()

void WorldSession::HandleRepopRequestOpcode ( WorldPacket recvPacket)

Definition at line 57 of file MiscHandler.cpp.

58{
59 LOG_DEBUG("network", "WORLD: Recvd CMSG_REPOP_REQUEST Message");
60
61 recv_data.read_skip<uint8>();
62
64 return;
65
67 return; // silently return, client should display the error by itself
68
69 // the world update order is sessions, players, creatures
70 // the netcode runs in parallel with all of these
71 // creatures can kill players
72 // so if the server is lagging enough the player can
73 // release spirit after he's killed but before he is updated
75 {
76 LOG_DEBUG("network", "HandleRepopRequestOpcode: got request after player {} ({}) was killed and before he was updated",
77 GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString());
79 }
80
81 //this is spirit release confirm?
82 GetPlayer()->RemovePet(nullptr, PET_SAVE_NOT_IN_SLOT, true);
85}
@ PET_SAVE_NOT_IN_SLOT
Definition: PetDefines.h:45
@ JUST_DIED
Definition: Unit.h:317
@ SPELL_AURA_PREVENT_RESURRECTION
DeathState getDeathState()
Definition: Unit.h:1808

◆ HandleReportLag()

void WorldSession::HandleReportLag ( WorldPacket recvPacket)

Definition at line 256 of file TicketHandler.cpp.

257{
258 // just put the lag report into the database...
259 // can't think of anything else to do with it
260 uint32 lagType, mapId;
261 recv_data >> lagType;
262 recv_data >> mapId;
263 float x, y, z;
264 recv_data >> x;
265 recv_data >> y;
266 recv_data >> z;
267
269 stmt->SetData(0, GetPlayer()->GetGUID().GetCounter());
270 stmt->SetData (1, lagType);
271 stmt->SetData(2, mapId);
272 stmt->SetData (3, x);
273 stmt->SetData (4, y);
274 stmt->SetData (5, z);
275 stmt->SetData(6, GetLatency());
276 stmt->SetData(7, GameTime::GetGameTime().count());
277 CharacterDatabase.Execute(stmt);
278}
@ CHAR_INS_LAG_REPORT
uint32 GetLatency() const
Definition: WorldSession.h:499

◆ HandleReportPvPAFK()

void WorldSession::HandleReportPvPAFK ( WorldPacket recvData)

Definition at line 898 of file BattleGroundHandler.cpp.

899{
900 ObjectGuid playerGuid;
901 recvData >> playerGuid;
902 Player* reportedPlayer = ObjectAccessor::FindPlayer(playerGuid);
903
904 if (!reportedPlayer)
905 {
906 LOG_DEBUG("bg.battleground", "WorldSession::HandleReportPvPAFK: player not found");
907 return;
908 }
909
910 LOG_DEBUG("bg.battleground", "WorldSession::HandleReportPvPAFK: {} reported {}", _player->GetName(), reportedPlayer->GetName());
911
912 reportedPlayer->ReportedAfkBy(_player);
913}
void ReportedAfkBy(Player *reporter)
This player has been blamed to be inactive in a battleground.
Definition: Player.cpp:11117

◆ HandleRequestAccountData()

void WorldSession::HandleRequestAccountData ( WorldPacket recvPacket)

Definition at line 900 of file MiscHandler.cpp.

901{
902 LOG_DEBUG("network", "WORLD: Received CMSG_REQUEST_ACCOUNT_DATA");
903
904 uint32 type;
905 recv_data >> type;
906
907 LOG_DEBUG("network", "RAD: type {}", type);
908
909 if (type >= NUM_ACCOUNT_DATA_TYPES)
910 return;
911
913
914 uint32 size = adata->Data.size();
915
916 uLongf destSize = compressBound(size);
917
918 ByteBuffer dest;
919 dest.resize(destSize);
920
921 if (size && compress(dest.contents(), &destSize, (uint8 const*)adata->Data.c_str(), size) != Z_OK)
922 {
923 LOG_DEBUG("network", "RAD: Failed to compress account data");
924 return;
925 }
926
927 dest.resize(destSize);
928
929 WorldPacket data(SMSG_UPDATE_ACCOUNT_DATA, 8 + 4 + 4 + 4 + destSize);
930 data << (_player ? _player->GetGUID() : ObjectGuid::Empty); // player guid
931 data << uint32(type); // type (0-7)
932 data << uint32(adata->Time); // unix time
933 data << uint32(size); // decompressed length
934 data.append(dest); // compressed data
935 SendPacket(&data);
936}
AccountDataType
Definition: WorldSession.h:165
#define NUM_ACCOUNT_DATA_TYPES
Definition: WorldSession.h:176
@ SMSG_UPDATE_ACCOUNT_DATA
Definition: Opcodes.h:554
std::string Data
Definition: WorldSession.h:186
AccountData * GetAccountData(AccountDataType type)
Definition: WorldSession.h:447

◆ HandleRequestPartyMemberStatsOpcode()

void WorldSession::HandleRequestPartyMemberStatsOpcode ( WorldPacket recvData)

Definition at line 977 of file GroupHandler.cpp.

978{
979 LOG_DEBUG("network", "WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS");
980 ObjectGuid Guid;
981 recvData >> Guid;
982
983 Player* player = HashMapHolder<Player>::Find(Guid);
984 if (!player)
985 {
987 data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
988 data << Guid.WriteAsPacked();
991 SendPacket(&data);
992 return;
993 }
994
995 Pet* pet = player->GetPet();
996 Powers powerType = player->getPowerType();
997
998 WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4 + 2 + 2 + 2 + 1 + 2 * 6 + 8 + 1 + 8);
999 data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
1000 data << player->GetPackGUID();
1001
1006
1007 if (powerType != POWER_MANA)
1008 updateFlags |= GROUP_UPDATE_FLAG_POWER_TYPE;
1009
1010 if (pet)
1013
1014 if (player->GetVehicle())
1015 updateFlags |= GROUP_UPDATE_FLAG_VEHICLE_SEAT;
1016
1017 uint16 playerStatus = MEMBER_STATUS_ONLINE;
1018 if (player->IsPvP())
1019 playerStatus |= MEMBER_STATUS_PVP;
1020
1021 if (!player->IsAlive())
1022 {
1023 if (player->HasPlayerFlag(PLAYER_FLAGS_GHOST))
1024 playerStatus |= MEMBER_STATUS_GHOST;
1025 else
1026 playerStatus |= MEMBER_STATUS_DEAD;
1027 }
1028
1029 if (player->IsFFAPvP())
1030 playerStatus |= MEMBER_STATUS_PVP_FFA;
1031
1032 if (player->isAFK())
1033 playerStatus |= MEMBER_STATUS_AFK;
1034
1035 if (player->isDND())
1036 playerStatus |= MEMBER_STATUS_DND;
1037
1038 data << uint32(updateFlags);
1039 data << uint16(playerStatus); // GROUP_UPDATE_FLAG_STATUS
1040 data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP
1041 data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP
1042 if (updateFlags & GROUP_UPDATE_FLAG_POWER_TYPE)
1043 data << uint8(powerType);
1044
1045 data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER
1046 data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER
1047 data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL
1048 data << uint16(player->GetZoneId()); // GROUP_UPDATE_FLAG_ZONE
1049 data << uint16(player->GetPositionX()); // GROUP_UPDATE_FLAG_POSITION
1050 data << uint16(player->GetPositionY()); // GROUP_UPDATE_FLAG_POSITION
1051
1052 uint64 auraMask = 0;
1053 size_t maskPos = data.wpos();
1054 data << uint64(auraMask); // placeholder
1055 for (uint8 i = 0; i < MAX_AURAS_GROUP_UPDATE; ++i)
1056 {
1057 if (AuraApplication const* aurApp = player->GetVisibleAura(i))
1058 {
1059 auraMask |= uint64(1) << i;
1060 data << uint32(aurApp->GetBase()->GetId());
1061 data << uint8(aurApp->GetFlags());
1062 }
1063 }
1064
1065 data.put<uint64>(maskPos, auraMask); // GROUP_UPDATE_FLAG_AURAS
1066
1067 if (pet && (updateFlags & GROUP_UPDATE_FLAG_PET_GUID))
1068 data << pet->GetGUID();
1069
1070 data << std::string(pet ? pet->GetName() : ""); // GROUP_UPDATE_FLAG_PET_NAME
1071 data << uint16(pet ? pet->GetDisplayId() : 0); // GROUP_UPDATE_FLAG_PET_MODEL_ID
1072
1073 if (pet && (updateFlags & GROUP_UPDATE_FLAG_PET_CUR_HP))
1074 data << uint32(pet->GetHealth());
1075
1076 if (pet && (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_HP))
1077 data << uint32(pet->GetMaxHealth());
1078
1079 if (pet && (updateFlags & GROUP_UPDATE_FLAG_PET_POWER_TYPE))
1080 data << (uint8)pet->getPowerType();
1081
1082 if (pet && (updateFlags & GROUP_UPDATE_FLAG_PET_CUR_POWER))
1083 data << uint16(pet->GetPower(pet->getPowerType()));
1084
1085 if (pet && (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_POWER))
1086 data << uint16(pet->GetMaxPower(pet->getPowerType()));
1087
1088 uint64 petAuraMask = 0;
1089 maskPos = data.wpos();
1090 data << uint64(petAuraMask); // placeholder
1091 if (pet)
1092 {
1093 for (uint8 i = 0; i < MAX_AURAS_GROUP_UPDATE; ++i)
1094 {
1095 if (AuraApplication const* aurApp = pet->GetVisibleAura(i))
1096 {
1097 petAuraMask |= uint64(1) << i;
1098 data << uint32(aurApp->GetBase()->GetId());
1099 data << uint8(aurApp->GetFlags());
1100 }
1101 }
1102 }
1103
1104 data.put<uint64>(maskPos, petAuraMask); // GROUP_UPDATE_FLAG_PET_AURAS
1105
1106 if (updateFlags & GROUP_UPDATE_FLAG_VEHICLE_SEAT)
1107 data << uint32(player->GetVehicle()->GetVehicleInfo()->m_seatID[player->m_movementInfo.transport.seat]);
1108
1109 SendPacket(&data);
1110}
@ MEMBER_STATUS_OFFLINE
Definition: Group.h:59
@ POWER_MANA
@ SMSG_PARTY_MEMBER_STATS_FULL
Definition: Opcodes.h:784
VehicleEntry const * GetVehicleInfo() const
Definition: Vehicle.h:40
static T * Find(ObjectGuid guid)
uint32 m_seatID[MAX_VEHICLE_SEATS]

◆ HandleRequestPetInfo()

void WorldSession::HandleRequestPetInfo ( WorldPackets::Pet::RequestPetInfo packet)

Definition at line 1581 of file MiscHandler.cpp.

1582{
1583 /*
1584 LOG_DEBUG("network.opcode", "WORLD: CMSG_REQUEST_PET_INFO");
1585 recv_data.hexlike();
1586 */
1587
1588 if (_player->GetPet())
1590 else if (_player->GetCharm())
1592}
void CharmSpellInitialize()
Definition: Player.cpp:9506

◆ HandleRequestRaidInfoOpcode()

void WorldSession::HandleRequestRaidInfoOpcode ( WorldPacket recvData)

Definition at line 1112 of file GroupHandler.cpp.

1113{
1114 // every time the player checks the character screen
1116}
void SendRaidInfo()

◆ HandleRequestVehicleExit()

void WorldSession::HandleRequestVehicleExit ( WorldPacket recvData)

Definition at line 226 of file VehicleHandler.cpp.

227{
228 LOG_DEBUG("network", "WORLD: Recvd CMSG_REQUEST_VEHICLE_EXIT");
229
230 if (Vehicle* vehicle = GetPlayer()->GetVehicle())
231 {
232 if (VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(GetPlayer()))
233 {
234 if (seat->CanEnterOrExit())
236 else
237 LOG_ERROR("network.opcode", "Player {} tried to exit vehicle, but seatflags {} (ID: {}) don't permit that.",
238 GetPlayer()->GetGUID().ToString(), seat->m_ID, seat->m_flags);
239 }
240 }
241}

◆ HandleResetInstancesOpcode()

void WorldSession::HandleResetInstancesOpcode ( WorldPacket recvData)

Definition at line 1307 of file MiscHandler.cpp.

1308{
1309 LOG_DEBUG("network", "WORLD: CMSG_RESET_INSTANCES");
1310
1311 if (Group* group = _player->GetGroup())
1312 {
1313 if (group->IsLeader(_player->GetGUID()))
1314 group->ResetInstances(INSTANCE_RESET_ALL, false, _player);
1315 }
1316 else
1318}
@ INSTANCE_RESET_ALL
Definition: Map.h:805
static void ResetInstances(ObjectGuid guid, uint8 method, bool isRaid)
Reset all solo instances and optionally send a message on success for each.
Definition: PlayerMisc.cpp:195

◆ HandleResurrectResponseOpcode()

void WorldSession::HandleResurrectResponseOpcode ( WorldPacket recvPacket)

Definition at line 685 of file MiscHandler.cpp.

686{
687 LOG_DEBUG("network", "WORLD: Received CMSG_RESURRECT_RESPONSE");
688
689 ObjectGuid guid;
690 uint8 status;
691 recv_data >> guid;
692 recv_data >> status;
693
694 // Xinef: Prevent resurrect with prevent resurrection aura
695 if (GetPlayer()->IsAlive() || GetPlayer()->HasAuraType(SPELL_AURA_PREVENT_RESURRECTION))
696 return;
697
698 if (status == 0)
699 {
701 return;
702 }
703
704 if (!GetPlayer()->isResurrectRequestedBy(guid))
705 return;
706
708}
void ResurectUsingRequestData()
Definition: Player.cpp:12534
void clearResurrectRequestData()
Definition: Player.h:1775

◆ HandleSaveGuildEmblemOpcode()

void WorldSession::HandleSaveGuildEmblemOpcode ( WorldPackets::Guild::SaveGuildEmblem packet)

Definition at line 227 of file GuildHandler.cpp.

228{
229 EmblemInfo emblemInfo;
230 emblemInfo.ReadPacket(packet);
231
232 LOG_DEBUG("guild", "MSG_SAVE_GUILD_EMBLEM [{}]: Guid: [{}] Style: {}, Color: {}, BorderStyle: {}, BorderColor: {}, BackgroundColor: {}"
233 , GetPlayerInfo(), packet.Vendor.ToString(), emblemInfo.GetStyle()
234 , emblemInfo.GetColor(), emblemInfo.GetBorderStyle()
235 , emblemInfo.GetBorderColor(), emblemInfo.GetBackgroundColor());
236 if (GetPlayer()->GetNPCIfCanInteractWith(packet.Vendor, UNIT_NPC_FLAG_TABARDDESIGNER))
237 {
238 // Remove fake death
239 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
241
242 if (Guild* guild = GetPlayer()->GetGuild())
243 guild->HandleSetEmblem(this, emblemInfo);
244 else
245 Guild::SendSaveEmblemResult(this, ERR_GUILDEMBLEM_NOGUILD); // "You are not part of a guild!";
246 }
247 else
248 Guild::SendSaveEmblemResult(this, ERR_GUILDEMBLEM_INVALIDVENDOR); // "That's not an emblem vendor!"
249}
@ UNIT_NPC_FLAG_TABARDDESIGNER
Definition: Unit.h:535
@ ERR_GUILDEMBLEM_INVALIDVENDOR
Definition: Guild.h:228
@ ERR_GUILDEMBLEM_NOGUILD
Definition: Guild.h:225
uint32 GetStyle() const
Definition: Guild.h:250
uint32 GetColor() const
Definition: Guild.h:251
uint32 GetBackgroundColor() const
Definition: Guild.h:254
uint32 GetBorderStyle() const
Definition: Guild.h:252
void ReadPacket(WorldPackets::Guild::SaveGuildEmblem &packet)
Definition: Guild.cpp:684
uint32 GetBorderColor() const
Definition: Guild.h:253
static void SendSaveEmblemResult(WorldSession *session, GuildEmblemError errCode)
Definition: Guild.cpp:126

◆ HandleSelfResOpcode()

void WorldSession::HandleSelfResOpcode ( WorldPacket recvData)

Definition at line 627 of file SpellHandler.cpp.

628{
629 LOG_DEBUG("network", "WORLD: CMSG_SELF_RES"); // empty opcode
630
631 if (SpellInfo const* spell = sSpellMgr->GetSpellInfo(_player->GetUInt32Value(PLAYER_SELF_RES_SPELL)))
632 {
634 {
635 return; // silent return, client should display error by itself and not send this opcode
636 }
637
638 _player->CastSpell(_player, spell->Id);
640 }
641}
@ PLAYER_SELF_RES_SPELL
Definition: UpdateFields.h:370
@ SPELL_ATTR7_BYPASS_NO_RESURRECTION_AURA

◆ HandleSellItemOpcode()

void WorldSession::HandleSellItemOpcode ( WorldPacket recvPacket)

Definition at line 728 of file ItemHandler.cpp.

729{
730 LOG_DEBUG("network", "WORLD: Received CMSG_SELL_ITEM");
731 ObjectGuid vendorguid, itemguid;
732 uint32 count;
733
734 recvData >> vendorguid >> itemguid >> count;
735
736 if (!itemguid)
737 return;
738
740 if (!creature)
741 {
742 LOG_DEBUG("network", "WORLD: HandleSellItemOpcode - Unit ({}) not found or you can not interact with him.", vendorguid.ToString());
743 _player->SendSellError(SELL_ERR_CANT_FIND_VENDOR, nullptr, itemguid, 0);
744 return;
745 }
746
748 {
750 return;
751 }
752
753 // remove fake death
754 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
756
757 Item* pItem = _player->GetItemByGuid(itemguid);
758 if (pItem)
759 {
760 if (!sScriptMgr->CanSellItem(_player, pItem, creature))
761 return;
762
763 // prevent sell not owner item
764 if (_player->GetGUID() != pItem->GetOwnerGUID())
765 {
766 _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid, 0);
767 return;
768 }
769
770 // prevent sell non empty bag by drag-and-drop at vendor's item list
771 if (pItem->IsNotEmptyBag())
772 {
773 _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid, 0);
774 return;
775 }
776
777 // prevent sell currently looted item
778 if (_player->GetLootGUID() == pItem->GetGUID())
779 {
780 _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid, 0);
781 return;
782 }
783
784 // prevent selling item for sellprice when the item is still refundable
785 // this probably happens when right clicking a refundable item, the client sends both
786 // CMSG_SELL_ITEM and CMSG_REFUND_ITEM (unverified)
788 return; // Therefore, no feedback to client
789
790 // special case at auto sell (sell all)
791 if (count == 0)
792 {
793 count = pItem->GetCount();
794 }
795 else
796 {
797 // prevent sell more items that exist in stack (possible only not from client)
798 if (count > pItem->GetCount())
799 {
800 _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid, 0);
801 return;
802 }
803 }
804
805 ItemTemplate const* pProto = pItem->GetTemplate();
806 if (pProto)
807 {
808 if (pProto->SellPrice > 0)
809 {
810 uint32 money = pProto->SellPrice * count;
811 if (_player->GetMoney() >= MAX_MONEY_AMOUNT - money) // prevent exceeding gold limit
812 {
814 _player->SendSellError(SELL_ERR_UNK, creature, itemguid, 0);
815 return;
816 }
817
818 if (sWorld->getBoolConfig(CONFIG_ITEMDELETE_VENDOR))
819 recoveryItem(pItem);
820
821 if (count < pItem->GetCount()) // need split items
822 {
823 Item* pNewItem = pItem->CloneItem(count, _player);
824 if (!pNewItem)
825 {
826 LOG_ERROR("network.opcode", "WORLD: HandleSellItemOpcode - could not create clone of item {}; count = {}", pItem->GetEntry(), count);
827 _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid, 0);
828 return;
829 }
830
831 pItem->SetCount(pItem->GetCount() - count);
832 _player->ItemRemovedQuestCheck(pItem->GetEntry(), count);
833 if (_player->IsInWorld())
836
837 _player->AddItemToBuyBackSlot(pNewItem);
838 if (_player->IsInWorld())
839 pNewItem->SendUpdateToPlayer(_player);
840 }
841 else
842 {
843 _player->ItemRemovedQuestCheck(pItem->GetEntry(), pItem->GetCount());
844 _player->RemoveItem(pItem->GetBagSlot(), pItem->GetSlot(), true);
848 }
849
850 _player->ModifyMoney(money);
852 }
853 else
854 _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid, 0);
855 return;
856 }
857 }
858 _player->SendSellError(SELL_ERR_CANT_FIND_ITEM, creature, itemguid, 0);
859 return;
860}
@ CREATURE_FLAG_EXTRA_NO_SELL_VENDOR
Definition: CreatureData.h:61
@ SELL_ERR_UNK
Definition: Item.h:153
@ SELL_ERR_CANT_SELL_TO_THIS_MERCHANT
Definition: Item.h:155
@ SELL_ERR_CANT_FIND_ITEM
Definition: Item.h:149
@ SELL_ERR_CANT_SELL_ITEM
Definition: Item.h:150
@ ITEM_FIELD_FLAG_REFUNDABLE
Definition: ItemTemplate.h:122
@ ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS
Definition: DBCEnums.h:178
void RemoveFromUpdateQueueOf(Player *player)
Definition: Item.cpp:766
ObjectGuid GetOwnerGUID() const
Definition: Item.h:225
void AddItemToBuyBackSlot(Item *pItem)

◆ HandleSendMail()

void WorldSession::HandleSendMail ( WorldPacket recvData)

accountBound

Definition at line 62 of file MailHandler.cpp.

63{
64 ObjectGuid mailbox;
65 uint64 unk3;
66 std::string receiver, subject, body;
67 uint32 unk1, unk2, money, COD;
68 uint8 unk4;
69
70 recvData >> mailbox;
71 recvData >> receiver;
72
73 recvData >> subject;
74
75 // prevent client crash
76 if (subject.find("| |") != std::string::npos || body.find("| |") != std::string::npos)
77 {
78 return;
79 }
80
81 recvData >> body;
82
83 recvData >> unk1; // stationery?
84 recvData >> unk2; // 0x00000000
85
86 uint8 items_count;
87 recvData >> items_count; // attached items count
88
89 if (items_count > MAX_MAIL_ITEMS) // client limit
90 {
92 recvData.rfinish(); // set to end to avoid warnings spam
93 return;
94 }
95
96 ObjectGuid itemGUIDs[MAX_MAIL_ITEMS];
97
98 for (uint8 i = 0; i < items_count; ++i)
99 {
100 recvData.read_skip<uint8>(); // item slot in mail, not used
101 recvData >> itemGUIDs[i];
102 }
103
104 recvData >> money >> COD; // money and cod
105 recvData >> unk3; // const 0
106 recvData >> unk4; // const 0
107
108 // packet read complete, now do check
109
110 if (!CanOpenMailBox(mailbox))
111 return;
112
113 if (receiver.empty())
114 return;
115
116 Player* player = _player;
117
118 if (player->getLevel() < sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ))
119 {
121 return;
122 }
123
124 ObjectGuid receiverGuid;
125 if (normalizePlayerName(receiver))
126 {
127 receiverGuid = sCharacterCache->GetCharacterGuidByName(receiver);
128 }
129
130 if (!receiverGuid)
131 {
132 LOG_DEBUG("network.opcode", "Player {} is sending mail to {} (GUID: not existed!) with subject {} and body {} includes {} items, {} copper and {} COD copper with unk1 = {}, unk2 = {}",
133 player->GetGUID().ToString(), receiver, subject, body, items_count, money, COD, unk1, unk2);
135 return;
136 }
137
138 LOG_DEBUG("network.opcode", "Player {} is sending mail to {} ({}) with subject {} and body {} includes {} items, {} copper and {} COD copper with unk1 = {}, unk2 = {}",
139 player->GetGUID().ToString(), receiver, receiverGuid.ToString(), subject, body, items_count, money, COD, unk1, unk2);
140
141 if (player->GetGUID() == receiverGuid)
142 {
144 return;
145 }
146
147 if (money && COD) // cannot send money in a COD mail
148 {
149 LOG_ERROR("network.opcode", "{} attempt to dupe money!!!.", receiver);
151 return;
152 }
153
154 uint32 cost = items_count ? 30 * items_count : 30; // price hardcoded in client
155
156 uint32 reqmoney = cost + money;
157
158 // Check for overflow
159 if (reqmoney < money)
160 {
162 return;
163 }
164
165 if (!player->HasEnoughMoney(reqmoney))
166 {
168 return;
169 }
170
171 Player* receive = ObjectAccessor::FindConnectedPlayer(receiverGuid);
172
173 uint32 rc_teamId = TEAM_NEUTRAL;
174 uint16 mails_count = 0; //do not allow to send to one player more than 100 mails
175
176 if (receive)
177 {
178 rc_teamId = receive->GetTeamId();
179 mails_count = receive->GetMailSize();
180 }
181 else
182 {
183 // xinef: get data from global storage
184 if (CharacterCacheEntry const* playerData = sCharacterCache->GetCharacterCacheByGuid(receiverGuid))
185 {
186 rc_teamId = Player::TeamIdForRace(playerData->Race);
187 mails_count = playerData->MailCount;
188 }
189 }
190 //do not allow to have more than 100 mails in mailbox.. mails count is in opcode uint8!!! - so max can be 255..
191 if (mails_count > 100)
192 {
194 return;
195 }
196 // test the receiver's Faction... or all items are account bound
197 // Xinef: check for boa items, not used currently
198 /*bool accountBound = items_count && !money && !COD ? true : false;
199 for (uint8 i = 0; i < items_count; ++i)
200 {
201 Item* item = player->GetItemByGuid(itemGUIDs[i]);
202 if (item)
203 {
204 ItemTemplate const* itemProto = item->GetTemplate();
205 if (!itemProto || !(itemProto->Flags & ITEM_FLAG_IS_BOUND_TO_ACCOUNT))
206 {
207 accountBound = false;
208 break;
209 }
210 }
211 }*/
212
213 uint32 rc_account = receive ? receive->GetSession()->GetAccountId() : sCharacterCache->GetCharacterAccountIdByGuid(receiverGuid);
214
215 if ( GetAccountId() != rc_account && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL) && player->GetTeamId() != rc_teamId && AccountMgr::IsPlayerAccount(GetSecurity()))
216 {
218 return;
219 }
220
221 Item* items[MAX_MAIL_ITEMS];
222
223 for (uint8 i = 0; i < items_count; ++i)
224 {
225 if (!itemGUIDs[i])
226 {
228 return;
229 }
230
231 Item* item = player->GetItemByGuid(itemGUIDs[i]);
232
233 // prevent sending bag with items (cheat: can be placed in bag after adding equipped empty bag to mail)
234 if (!item)
235 {
237 return;
238 }
239
240 if (!item->CanBeTraded(true))
241 {
243 return;
244 }
245
246 if (item->IsBoundAccountWide() && item->IsSoulBound() && GetAccountId() != rc_account)
247 {
249 return;
250 }
251
253 {
255 return;
256 }
257
259 {
261 return;
262 }
263
264 if (item->IsNotEmptyBag())
265 {
267 return;
268 }
269
270 if (!sScriptMgr->CanSendMail(player, receiverGuid, mailbox, subject, body, money, COD, item))
271 {
272 return;
273 }
274
275 items[i] = item;
276 }
277
278 player->SendMailResult(0, MAIL_SEND, MAIL_OK);
279
280 player->ModifyMoney(-int32(reqmoney));
282
283 bool needItemDelay = false;
284
285 MailDraft draft(subject, body);
286
287 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
288
289 if (items_count > 0 || money > 0)
290 {
291 if (items_count > 0)
292 {
293 for (uint8 i = 0; i < items_count; ++i)
294 {
295 Item* item = items[i];
296
297 item->SetNotRefundable(GetPlayer()); // makes the item no longer refundable
298 player->MoveItemFromInventory(items[i]->GetBagSlot(), item->GetSlot(), true);
299
300 item->DeleteFromInventoryDB(trans); // deletes item from character's inventory
301 if (item->GetState() == ITEM_UNCHANGED)
302 item->FSetState(ITEM_CHANGED); // pussywizard: so the item will be saved and owner will be updated in database
303 item->SetOwnerGUID(receiverGuid);
304 item->SaveToDB(trans); // recursive and not have transaction guard into self, item not in inventory and can be save standalone
305
306 draft.AddItem(item);
307 }
308
309 // if item send to character at another account, then apply item delivery delay
310 needItemDelay = GetAccountId() != rc_account;
311 }
312
313 if( money >= 10 * GOLD )
314 {
316 CharacterDatabase.Execute("INSERT INTO log_money VALUES({}, {}, \"{}\", \"{}\", {}, \"{}\", {}, \"{}\", NOW(), {})",
317 GetAccountId(), player->GetGUID().GetCounter(), player->GetName(), player->GetSession()->GetRemoteAddress(), rc_account, receiver, money, subject, 5);
318 }
319 }
320
321 // If theres is an item, there is a one hour delivery delay if sent to another account's character.
322 uint32 deliver_delay = needItemDelay ? sWorld->getIntConfig(CONFIG_MAIL_DELIVERY_DELAY) : 0;
323
324 // don't ask for COD if there are no items
325 if (items_count == 0)
326 COD = 0;
327
328 // will delete item or place to receiver mail list
329 draft
330 .AddMoney(money)
331 .AddCOD(COD)
332 .SendMailTo(trans, MailReceiver(receive, receiverGuid.GetCounter()), MailSender(player), body.empty() ? MAIL_CHECK_MASK_COPIED : MAIL_CHECK_MASK_HAS_BODY, deliver_delay);
333
334 player->SaveInventoryAndGoldToDB(trans);
335 CharacterDatabase.CommitTransaction(trans);
336}
@ EQUIP_ERR_MAIL_BOUND_ITEM
Definition: Item.h:113
@ EQUIP_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS
Definition: Item.h:72
@ EQUIP_ERR_ARTEFACTS_ONLY_FOR_OWN_CHARACTERS
Definition: Item.h:122
@ MAIL_CHECK_MASK_HAS_BODY
Definition: Mail.h:52
#define MAX_MAIL_ITEMS
Definition: Mail.h:34
@ LANG_MAIL_SENDER_REQ
Definition: Language.h:1161
@ CONFIG_MAIL_LEVEL_REQ
Definition: IWorld.h:292
@ CONFIG_MAIL_DELIVERY_DELAY
Definition: IWorld.h:256
@ CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL
Definition: IWorld.h:83
@ ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL
Definition: DBCEnums.h:184
@ MAIL_SEND
@ MAIL_ERR_NOT_YOUR_TEAM
@ MAIL_ERR_CANT_SEND_WRAPPED_COD
@ MAIL_ERR_RECIPIENT_CAP_REACHED
@ MAIL_ERR_RECIPIENT_NOT_FOUND
@ MAIL_ERR_TOO_MANY_ATTACHMENTS
@ MAIL_ERR_MAIL_ATTACHMENT_INVALID
@ MAIL_ERR_CANNOT_SEND_TO_SELF
bool IsBoundAccountWide() const
Definition: Item.h:231
bool IsSoulBound() const
Definition: Item.h:230
ItemUpdateState GetState() const
Definition: Item.h:315
void SetNotRefundable(Player *owner, bool changestate=true, CharacterDatabaseTransaction *trans=nullptr)
Definition: Item.cpp:1202
void FSetState(ItemUpdateState state)
Definition: Item.h:321
void SetOwnerGUID(ObjectGuid guid)
Definition: Item.h:226
uint32 GetMailSize()
Definition: Player.h:1608

◆ HandleSetActionBarToggles()

void WorldSession::HandleSetActionBarToggles ( WorldPacket recvData)

Definition at line 1006 of file MiscHandler.cpp.

1007{
1008 uint8 ActionBar;
1009
1010 recv_data >> ActionBar;
1011
1012 if (!GetPlayer()) // ignore until not logged (check needed because STATUS_AUTHED)
1013 {
1014 if (ActionBar != 0)
1015 LOG_ERROR("network.opcode", "WorldSession::HandleSetActionBarToggles in not logged state with value: {}, ignored", uint32(ActionBar));
1016 return;
1017 }
1018
1019 GetPlayer()->SetByteValue(PLAYER_FIELD_BYTES, 2, ActionBar);
1020}
@ PLAYER_FIELD_BYTES
Definition: UpdateFields.h:368

◆ HandleSetActionButtonOpcode()

void WorldSession::HandleSetActionButtonOpcode ( WorldPacket recvPacket)

Definition at line 938 of file MiscHandler.cpp.

939{
940 LOG_DEBUG("network", "WORLD: Received CMSG_SET_ACTION_BUTTON");
941 uint8 button;
942 uint32 packetData;
943 recv_data >> button >> packetData;
944
945 uint32 action = ACTION_BUTTON_ACTION(packetData);
946 uint8 type = ACTION_BUTTON_TYPE(packetData);
947
948 LOG_DEBUG("network.opcode", "BUTTON: {} ACTION: {} TYPE: {}", button, action, type);
949 if (!packetData)
950 {
951 LOG_DEBUG("network.opcode", "MISC: Remove action from button {}", button);
952 GetPlayer()->removeActionButton(button);
953 }
954 else
955 {
956 switch (type)
957 {
960 LOG_DEBUG("network.opcode", "MISC: Added Macro {} into button {}", action, button);
961 break;
963 LOG_DEBUG("network.opcode", "MISC: Added EquipmentSet {} into button {}", action, button);
964 break;
966 LOG_DEBUG("network.opcode", "MISC: Added Spell {} into button {}", action, button);
967 break;
969 LOG_DEBUG("network.opcode", "MISC: Added Item {} into button {}", action, button);
970 break;
971 default:
972 LOG_ERROR("network.opcode", "MISC: Unknown action button type {} for action {} into button {} for player {} ({})",
973 type, action, button, _player->GetName(), _player->GetGUID().ToString());
974 return;
975 }
976 GetPlayer()->addActionButton(button, action, type);
977 }
978}
@ ACTION_BUTTON_EQSET
Definition: Player.h:232
@ ACTION_BUTTON_MACRO
Definition: Player.h:233
@ ACTION_BUTTON_ITEM
Definition: Player.h:235
@ ACTION_BUTTON_CMACRO
Definition: Player.h:234
@ ACTION_BUTTON_SPELL
Definition: Player.h:230
#define ACTION_BUTTON_TYPE(X)
Definition: Player.h:250
#define ACTION_BUTTON_ACTION(X)
Definition: Player.h:249
ActionButton * addActionButton(uint8 button, uint32 action, uint8 type)
Definition: Player.cpp:5510
void removeActionButton(uint8 button)
Definition: Player.cpp:5525

◆ HandleSetActiveMoverOpcode()

void WorldSession::HandleSetActiveMoverOpcode ( WorldPacket recvData)

Definition at line 714 of file MovementHandler.cpp.

715{
716 LOG_DEBUG("network", "WORLD: Recvd CMSG_SET_ACTIVE_MOVER");
717
718 ObjectGuid guid;
719 recvData >> guid;
720
721 if (GetPlayer()->IsInWorld() && _player->m_mover && _player->m_mover->IsInWorld())
722 {
723 if (_player->m_mover->GetGUID() != guid)
724 LOG_ERROR("network.opcode", "HandleSetActiveMoverOpcode: incorrect mover guid: mover is {} and should be {}",
725 guid.ToString(), _player->m_mover->GetGUID().ToString());
726 }
727}

◆ HandleSetActiveVoiceChannel()

void WorldSession::HandleSetActiveVoiceChannel ( WorldPacket recvData)

Definition at line 37 of file VoiceChatHandler.cpp.

38{
39 LOG_DEBUG("network", "WORLD: CMSG_SET_ACTIVE_VOICE_CHANNEL");
40 recvData.read_skip<uint32>();
41 recvData.read_skip<char*>();
42}

◆ HandleSetAmmoOpcode()

void WorldSession::HandleSetAmmoOpcode ( WorldPacket recvPacket)

Definition at line 1152 of file ItemHandler.cpp.

1153{
1154 if (!_player->IsAlive())
1155 {
1156 _player->SendEquipError(EQUIP_ERR_YOU_ARE_DEAD, nullptr, nullptr);
1157 return;
1158 }
1159
1160 LOG_DEBUG("network", "WORLD: CMSG_SET_AMMO");
1161 uint32 item;
1162
1163 recvData >> item;
1164
1165 if (item)
1166 {
1167 if (!_player->GetItemCount(item))
1168 {
1170 return;
1171 }
1172
1173 _player->SetAmmo(item);
1174 }
1175 else
1177}
uint32 GetItemCount(uint32 item, bool inBankAlso=false, Item *skipItem=nullptr) const
void RemoveAmmo()
void SetAmmo(uint32 item)

◆ HandleSetChannelWatch()

void WorldSession::HandleSetChannelWatch ( WorldPacket recvPacket)

Definition at line 308 of file ChannelHandler.cpp.

309{
310 std::string channelName;
311 recvPacket >> channelName;
312
314
315 if (channelName.empty())
316 return;
317
319 if (Channel* channel = cMgr->GetChannel(channelName, nullptr, false))
320 channel->AddWatching(GetPlayer());
321}
void ClearChannelWatch()
Definition: Player.cpp:4898

◆ HandleSetContactNotesOpcode()

void WorldSession::HandleSetContactNotesOpcode ( WorldPacket recvPacket)

Definition at line 153 of file Socialhandler.cpp.

154{
155 ObjectGuid guid;
156 std::string note;
157 recv_data >> guid >> note;
158 _player->GetSocial()->SetFriendNote(guid, note);
159}

◆ HandleSetDungeonDifficultyOpcode()

void WorldSession::HandleSetDungeonDifficultyOpcode ( WorldPacket recvData)

Definition at line 1320 of file MiscHandler.cpp.

1321{
1322 LOG_DEBUG("network", "MSG_SET_DUNGEON_DIFFICULTY");
1323
1324 uint32 mode;
1325 recv_data >> mode;
1326
1327 if (mode >= MAX_DUNGEON_DIFFICULTY)
1328 return;
1329
1330 if (Difficulty(mode) == _player->GetDungeonDifficulty())
1331 return;
1332
1333 Group* group = _player->GetGroup();
1334 if (group)
1335 {
1336 if (group->IsLeader(_player->GetGUID()))
1337 {
1338 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
1339 {
1340 Player* groupGuy = itr->GetSource();
1341 if (!groupGuy)
1342 continue;
1343
1344 if (!groupGuy->IsInWorld())
1345 {
1346 _player->SendDungeonDifficulty(group != nullptr);
1347 return;
1348 }
1349
1350 if (groupGuy->GetGUID() == _player->GetGUID() ? groupGuy->GetMap()->IsDungeon() : groupGuy->GetMap()->IsNonRaidDungeon())
1351 {
1352 _player->SendDungeonDifficulty(group != nullptr);
1353 return;
1354 }
1355 }
1356
1358 group->SetDungeonDifficulty(Difficulty(mode));
1359 }
1360 }
1361 else
1362 {
1363 if (_player->FindMap() && _player->FindMap()->IsDungeon())
1364 {
1365 _player->SendDungeonDifficulty(group != nullptr);
1366 return;
1367 }
1370 }
1371}
@ INSTANCE_RESET_CHANGE_DIFFICULTY
Definition: Map.h:806
#define MAX_DUNGEON_DIFFICULTY
Definition: DBCEnums.h:286
void SetDungeonDifficulty(Difficulty dungeon_difficulty)
Definition: Player.h:1873
void SetDungeonDifficulty(Difficulty difficulty)
Definition: Group.cpp:2013
void ResetInstances(uint8 method, bool isRaid, Player *leader)
Definition: Group.cpp:2055
bool IsNonRaidDungeon() const
Definition: Map.h:448

◆ HandleSetFactionAtWar()

void WorldSession::HandleSetFactionAtWar ( WorldPacket recvData)

Definition at line 1250 of file CharacterHandler.cpp.

1251{
1252 LOG_DEBUG("network.opcode", "WORLD: Received CMSG_SET_FACTION_ATWAR");
1253
1254 uint32 repListID;
1255 uint8 flag;
1256
1257 recvData >> repListID;
1258 recvData >> flag;
1259
1260 GetPlayer()->GetReputationMgr().SetAtWar(repListID, flag);
1261}
void SetAtWar(RepListID repListID, bool on)

◆ HandleSetFactionCheat()

void WorldSession::HandleSetFactionCheat ( WorldPacket recvData)

Definition at line 1264 of file CharacterHandler.cpp.

1265{
1266 LOG_ERROR("network.opcode", "WORLD SESSION: HandleSetFactionCheat, not expected call, please report.");
1268}

◆ HandleSetFactionInactiveOpcode()

void WorldSession::HandleSetFactionInactiveOpcode ( WorldPacket recvData)

Definition at line 1306 of file CharacterHandler.cpp.

1307{
1308 LOG_DEBUG("network.opcode", "WORLD: Received CMSG_SET_FACTION_INACTIVE");
1309 uint32 replistid;
1310 uint8 inactive;
1311 recvData >> replistid >> inactive;
1312
1313 _player->GetReputationMgr().SetInactive(replistid, inactive);
1314}
void SetInactive(RepListID repListID, bool on)

◆ HandleSetGuildBankTabText()

void WorldSession::HandleSetGuildBankTabText ( WorldPackets::Guild::GuildBankSetTabText packet)

Definition at line 399 of file GuildHandler.cpp.

400{
401 LOG_DEBUG("guild", "CMSG_SET_GUILD_BANK_TEXT [{}]: TabId: {}, Text: {}", GetPlayerInfo(), packet.Tab, packet.TabText);
402
403 if (Guild* guild = GetPlayer()->GetGuild())
404 guild->SetBankTabText(packet.Tab, packet.TabText);
405}
String< 500, Strings::NoHyperlinks > TabText
Definition: GuildPackets.h:585

◆ HandleSetPlayerDeclinedNames()

void WorldSession::HandleSetPlayerDeclinedNames ( WorldPacket recvData)

Definition at line 1424 of file CharacterHandler.cpp.

1425{
1426 // pussywizard:
1427 if (!sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED))
1428 return;
1429
1430 ObjectGuid guid;
1431 recvData >> guid;
1432
1433 // not accept declined names for unsupported languages
1434 std::string name;
1435 if (!sCharacterCache->GetCharacterNameByGuid(guid, name))
1436 {
1438 return;
1439 }
1440
1441 std::wstring wname;
1442 if (!Utf8toWStr(name, wname))
1443 {
1445 return;
1446 }
1447
1448 if (!isCyrillicCharacter(wname[0])) // name already stored as only single alphabet using
1449 {
1451 return;
1452 }
1453
1454 std::string name2;
1455 DeclinedName declinedname;
1456
1457 recvData >> name2;
1458
1459 if (name2 != name) // character have different name
1460 {
1462 return;
1463 }
1464
1465 for (int i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
1466 {
1467 recvData >> declinedname.name[i];
1468 if (!normalizePlayerName(declinedname.name[i]))
1469 {
1471 return;
1472 }
1473 }
1474
1475 if (!ObjectMgr::CheckDeclinedNames(wname, declinedname))
1476 {
1478 return;
1479 }
1480
1481 for (int i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
1482 CharacterDatabase.EscapeString(declinedname.name[i]);
1483
1484 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
1485
1487 stmt->SetData(0, guid.GetCounter());
1488 trans->Append(stmt);
1489
1490 stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_DECLINED_NAME);
1491 stmt->SetData(0, guid.GetCounter());
1492
1493 for (uint8 i = 0; i < 5; i++)
1494 stmt->SetData(i + 1, declinedname.name[i]);
1495
1496 trans->Append(stmt);
1497
1498 CharacterDatabase.CommitTransaction(trans);
1499
1501}
bool isCyrillicCharacter(wchar_t wchar)
Definition: Util.h:154
@ CHAR_INS_CHAR_DECLINED_NAME
@ DECLINED_NAMES_RESULT_SUCCESS
Definition: WorldSession.h:216
@ DECLINED_NAMES_RESULT_ERROR
Definition: WorldSession.h:217
void SendSetPlayerDeclinedNamesResult(DeclinedNameResult result, ObjectGuid guid)

◆ HandleSetRaidDifficultyOpcode()

void WorldSession::HandleSetRaidDifficultyOpcode ( WorldPacket recvData)

Definition at line 1373 of file MiscHandler.cpp.

1374{
1375 LOG_DEBUG("network", "MSG_SET_RAID_DIFFICULTY");
1376
1377 uint32 mode;
1378 recv_data >> mode;
1379
1380 if (mode >= MAX_RAID_DIFFICULTY)
1381 return;
1382
1383 if (Difficulty(mode) == _player->GetRaidDifficulty())
1384 return;
1385
1386 Group* group = _player->GetGroup();
1387 if (group)
1388 {
1389 if (group->IsLeader(_player->GetGUID()))
1390 {
1391 std::set<uint32> foundMaps;
1392 std::set<Map*> foundMapsPtr;
1393 Map* currMap = nullptr;
1394
1395 if (uint32 preventionTime = group->GetDifficultyChangePreventionTime())
1396 {
1397 switch (group->GetDifficultyChangePreventionReason())
1398 {
1400 ChatHandler(this).PSendSysMessage("Raid was in combat recently and may not change difficulty again for %u sec.", preventionTime);
1401 break;
1403 default:
1404 ChatHandler(this).PSendSysMessage("Raid difficulty has changed recently, and may not change again for %u sec.", preventionTime);
1405 break;
1406 }
1407
1408 _player->SendRaidDifficulty(group != nullptr);
1409 return;
1410 }
1411
1412 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
1413 {
1414 Player* groupGuy = itr->GetSource();
1415 if (!groupGuy)
1416 continue;
1417
1418 if (!groupGuy->IsInWorld())
1419 {
1420 _player->SendRaidDifficulty(group != nullptr);
1421 return;
1422 }
1423
1424 if (IsSharedDifficultyMap(groupGuy->GetMap()->GetId()) && (_player->GetRaidDifficulty() >= 0 && uint32(mode % 2) == uint32(_player->GetRaidDifficulty() % 2)) && group->isRaidGroup())
1425 {
1426 if (!currMap)
1427 currMap = groupGuy->GetMap();
1428 foundMaps.insert(groupGuy->GetMap()->GetId());
1429 foundMapsPtr.insert(groupGuy->GetMap());
1430 if (foundMaps.size() > 1 || foundMapsPtr.size() > 1)
1431 {
1432 _player->SendRaidDifficulty(group != nullptr);
1433 return;
1434 }
1435
1436 if (!groupGuy->IsAlive() || groupGuy->IsInCombat() || groupGuy->GetVictim() || groupGuy->m_mover != groupGuy || groupGuy->IsNonMeleeSpellCast(true) || (!groupGuy->GetMotionMaster()->empty() && groupGuy->GetMotionMaster()->GetCurrentMovementGeneratorType() != IDLE_MOTION_TYPE)
1437 || !groupGuy->movespline->Finalized() || !groupGuy->GetMap()->ToInstanceMap() || !groupGuy->GetMap()->ToInstanceMap()->GetInstanceScript() || groupGuy->GetMap()->ToInstanceMap()->GetInstanceScript()->IsEncounterInProgress()
1438 || !groupGuy->Satisfy(sObjectMgr->GetAccessRequirement(groupGuy->GetMap()->GetId(), Difficulty(mode)), groupGuy->GetMap()->GetId(), false))
1439 {
1440 _player->SendRaidDifficulty(group != nullptr);
1441 return;
1442 }
1443 }
1444 else if (groupGuy->GetGUID() == _player->GetGUID() ? groupGuy->GetMap()->IsDungeon() : groupGuy->GetMap()->IsRaid())
1445 {
1446 _player->SendRaidDifficulty(group != nullptr);
1447 return;
1448 }
1449 }
1450
1451 Map* homeMap571 = sMapMgr->CreateMap(571, nullptr);
1452 Map* homeMap0 = sMapMgr->CreateMap(0, nullptr);
1453 ASSERT(homeMap0 && homeMap571);
1454
1455 std::map<Player*, Position> playerTeleport;
1456 // handle here all players in the instance that are not in the group
1457 if (currMap)
1458 for (Map::PlayerList::const_iterator itr = currMap->GetPlayers().begin(); itr != currMap->GetPlayers().end(); ++itr)
1459 if (Player* p = itr->GetSource())
1460 if (p->GetGroup() != group)
1461 {
1462 if (!p->IsInWorld() || !p->IsAlive() || p->IsInCombat() || p->GetVictim() || p->m_mover != p || p->IsNonMeleeSpellCast(true) || (!p->GetMotionMaster()->empty() && p->GetMotionMaster()->GetCurrentMovementGeneratorType() != IDLE_MOTION_TYPE)
1463 || !p->movespline->Finalized() || !p->GetMap()->ToInstanceMap() || !p->GetMap()->ToInstanceMap()->GetInstanceScript() || p->GetMap()->ToInstanceMap()->GetInstanceScript()->IsEncounterInProgress())
1464 {
1465 _player->SendRaidDifficulty(group != nullptr);
1466 return;
1467 }
1468 playerTeleport[p];
1469 }
1470 for (std::map<Player*, Position>::iterator itr = playerTeleport.begin(); itr != playerTeleport.end(); ++itr)
1471 {
1472 Player* p = itr->first;
1473 Map* oldMap = p->GetMap();
1474 oldMap->RemovePlayerFromMap(p, false);
1475 p->ResetMap();
1476 oldMap->AfterPlayerUnlinkFromMap();
1477 p->SetMap(homeMap0);
1478 p->Relocate(0.0f, 0.0f, 0.0f, 0.0f);
1479 if (!p->TeleportTo(571, 5790.20f, 2071.36f, 636.07f, 3.60f))
1480 p->GetSession()->KickPlayer("HandleSetRaidDifficultyOpcode 1");
1481 }
1482
1483 bool anyoneInside = false;
1484 playerTeleport.clear();
1485 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
1486 {
1487 Player* groupGuy = itr->GetSource();
1488 if (!groupGuy)
1489 continue;
1490
1491 if (IsSharedDifficultyMap(groupGuy->GetMap()->GetId()))
1492 {
1493 anyoneInside = true;
1494
1495 float x, y, z, o;
1496 groupGuy->GetPosition(x, y, z, o);
1497 Map* oldMap = groupGuy->GetMap();
1498 oldMap->RemovePlayerFromMap(groupGuy, false);
1499 groupGuy->ResetMap();
1500 oldMap->AfterPlayerUnlinkFromMap();
1501 groupGuy->SetMap(homeMap571);
1502 groupGuy->Relocate(5790.20f, 2071.36f, 636.07f, 3.60f);
1503 Position dest = {x, y, z + 0.1f, o};
1504 playerTeleport[groupGuy] = dest;
1505 }
1506 }
1507
1508 if (!anyoneInside) // pussywizard: don't reset if changing ICC/RS difficulty while inside
1510 group->SetRaidDifficulty(Difficulty(mode));
1512
1513 for (std::map<Player*, Position>::iterator itr = playerTeleport.begin(); itr != playerTeleport.end(); ++itr)
1514 {
1515 itr->first->SetRaidDifficulty(Difficulty(mode)); // needed for teleport not to fail
1516 if (!itr->first->TeleportTo(*(foundMaps.begin()), itr->second.GetPositionX(), itr->second.GetPositionY(), itr->second.GetPositionZ(), itr->second.GetOrientation()))
1517 itr->first->GetSession()->KickPlayer("HandleSetRaidDifficultyOpcode 2");
1518 }
1519 }
1520 }
1521 else
1522 {
1523 if (_player->FindMap() && _player->FindMap()->IsDungeon())
1524 {
1525 _player->SendRaidDifficulty(group != nullptr);
1526 return;
1527 }
1530 }
1531}
bool IsSharedDifficultyMap(uint32 mapid)
Definition: DBCStores.cpp:817
@ DIFFICULTY_PREVENTION_CHANGE_RECENTLY_CHANGED
Definition: Group.h:133
@ DIFFICULTY_PREVENTION_CHANGE_BOSS_KILLED
Definition: Group.h:134
@ IDLE_MOTION_TYPE
Definition: MotionMaster.h:37
#define MAX_RAID_DIFFICULTY
Definition: DBCEnums.h:287
Difficulty GetRaidDifficulty() const
Definition: Player.h:1871
void SetRaidDifficulty(Difficulty raid_difficulty)
Definition: Player.h:1874
bool Satisfy(DungeonProgressionRequirements const *ar, uint32 target_map, bool report=false)
void SendRaidDifficulty(bool IsInGroup, int32 forcedDifficulty=-1)
Definition: PlayerMisc.cpp:177
void SetRaidDifficulty(Difficulty difficulty)
Definition: Group.cpp:2034
DifficultyPreventionChangeType GetDifficultyChangePreventionReason() const
Definition: Group.h:316
void SetDifficultyChangePrevention(DifficultyPreventionChangeType type)
Definition: Group.cpp:2472
uint32 GetDifficultyChangePreventionTime() const
Definition: Group.cpp:2467
virtual bool IsEncounterInProgress() const
bool IsRaid() const
Definition: Map.h:449
InstanceMap * ToInstanceMap()
Definition: Map.h:544
PlayerList const & GetPlayers() const
Definition: Map.h:484
InstanceScript * GetInstanceScript()
Definition: Map.h:825
iterator begin()
Definition: MapRefMgr.h:36
iterator end()
Definition: MapRefMgr.h:37
MovementGeneratorType GetCurrentMovementGeneratorType() const
bool empty() const
Definition: MotionMaster.h:146

◆ HandleSetSavedInstanceExtend()

void WorldSession::HandleSetSavedInstanceExtend ( WorldPacket recvData)

Definition at line 790 of file CalendarHandler.cpp.

791{
792 uint32 mapId, difficulty;
793 uint8 toggleExtendOn;
794 recvData >> mapId >> difficulty >> toggleExtendOn;
795
796 MapEntry const* entry = sMapStore.LookupEntry(mapId);
797 if (!entry || !entry->IsRaid())
798 return;
799
800 InstancePlayerBind* instanceBind = sInstanceSaveMgr->PlayerGetBoundInstance(GetPlayer()->GetGUID(), mapId, Difficulty(difficulty));
801 if (!instanceBind || !instanceBind->perm || (bool)toggleExtendOn == instanceBind->extended)
802 return;
803
804 instanceBind->extended = (bool)toggleExtendOn;
805
806 // update in db
808 stmt->SetData(0, toggleExtendOn ? 1 : 0);
809 stmt->SetData(1, GetPlayer()->GetGUID().GetCounter());
810 stmt->SetData(2, instanceBind->save->GetInstanceId());
811 CharacterDatabase.Execute(stmt);
812
813 SendCalendarRaidLockoutUpdated(instanceBind->save, (bool)toggleExtendOn);
814}
@ CHAR_UPD_CHAR_INSTANCE_EXTENDED
InstanceSave * save
void SendCalendarRaidLockoutUpdated(InstanceSave const *save, bool isExtended)

◆ HandleSetSelectionOpcode()

void WorldSession::HandleSetSelectionOpcode ( WorldPacket recvPacket)

Definition at line 532 of file MiscHandler.cpp.

533{
534 ObjectGuid guid;
535 recv_data >> guid;
536
537 if (!guid)
538 {
539 // Clear any active gossip related to current selection if not present at player's client
541 if (gossipMenu.GetSenderGUID() == _player->GetTarget())
542 {
544 }
545 }
546
547 _player->SetSelection(guid);
548
549 // Change target of current autoshoot spell
550 if (guid)
551 {
552 if (Spell* autoReapeatSpell = _player->GetCurrentSpell(CURRENT_AUTOREPEAT_SPELL))
553 {
554 if (autoReapeatSpell->m_targets.GetUnitTargetGUID() != guid)
555 {
556 if (Unit* unit = ObjectAccessor::GetUnit(*_player, guid))
557 {
558 if (unit->IsAlive() && !_player->IsFriendlyTo(unit) && unit->isTargetableForAttack(true, _player))
559 {
560 autoReapeatSpell->m_targets.SetUnitTarget(unit);
561 }
562 }
563 }
564 }
565 }
566}
void SetSelection(ObjectGuid guid)
Used for serverside target changes, does not apply to players.
Definition: Player.cpp:11265
bool IsFriendlyTo(Unit const *unit) const
Definition: Unit.cpp:10202
ObjectGuid GetTarget() const
Definition: Unit.h:2428

◆ HandleSetSheathedOpcode()

void WorldSession::HandleSetSheathedOpcode ( WorldPackets::Combat::SetSheathed packet)

Definition at line 74 of file CombatHandler.cpp.

75{
77 {
78 LOG_ERROR("network.opcode", "Unknown sheath state {} ??", packet.CurrentSheathState);
79 return;
80 }
81
83}
SheathState
Definition: Unit.h:125
#define MAX_SHEATH_STATE
Definition: Unit.h:131
void SetSheath(SheathState sheathed) override

◆ HandleSetTaxiBenchmarkOpcode()

void WorldSession::HandleSetTaxiBenchmarkOpcode ( WorldPacket recvData)

Definition at line 1594 of file MiscHandler.cpp.

1595{
1596 uint8 mode;
1597 recv_data >> mode;
1598
1600
1601 LOG_DEBUG("network", "Client used \"/timetest {}\" command", mode);
1602}
@ PLAYER_FLAGS_TAXI_BENCHMARK
Definition: Player.h:492

◆ HandleSetTitleOpcode()

void WorldSession::HandleSetTitleOpcode ( WorldPacket recvData)

Definition at line 1288 of file MiscHandler.cpp.

1289{
1290 LOG_DEBUG("network", "CMSG_SET_TITLE");
1291
1292 int32 title;
1293 recv_data >> title;
1294
1295 // -1 at none
1296 if (title > 0 && title < MAX_TITLE_INDEX)
1297 {
1298 if (!GetPlayer()->HasTitle(title))
1299 return;
1300 }
1301 else
1302 title = 0;
1303
1305}
@ PLAYER_CHOSEN_TITLE
Definition: UpdateFields.h:324
#define MAX_TITLE_INDEX
Definition: Player.h:555

◆ HandleSetTradeGoldOpcode()

void WorldSession::HandleSetTradeGoldOpcode ( WorldPacket recvPacket)

Definition at line 657 of file TradeHandler.cpp.

658{
659 uint32 gold;
660 recvPacket >> gold;
661
662 TradeData* my_trade = _player->GetTradeData();
663 if (!my_trade)
664 return;
665
666 my_trade->SetMoney(gold);
667}
TradeData * GetTradeData() const
Definition: Player.h:1344
void SetMoney(uint32 money)
Definition: TradeData.cpp:93

◆ HandleSetTradeItemOpcode()

void WorldSession::HandleSetTradeItemOpcode ( WorldPacket recvPacket)

Definition at line 669 of file TradeHandler.cpp.

670{
671 // send update
672 uint8 tradeSlot;
673 uint8 bag;
674 uint8 slot;
675
676 recvPacket >> tradeSlot;
677 recvPacket >> bag;
678 recvPacket >> slot;
679
680 TradeData* my_trade = _player->GetTradeData();
681 if (!my_trade)
682 return;
683
684 // invalid slot number
685 if (tradeSlot >= TRADE_SLOT_COUNT)
686 {
688 return;
689 }
690
691 // check cheating, can't fail with correct client operations
692 Item* item = _player->GetItemByPos(bag, slot);
693 if (!item || (tradeSlot != TRADE_SLOT_NONTRADED && !item->CanBeTraded(false, true)))
694 {
696 return;
697 }
698
699 ObjectGuid iGUID = item->GetGUID();
700
701 // prevent place single item into many trade slots using cheating and client bugs
702 if (my_trade->HasItem(iGUID))
703 {
704 // cheating attempt
706 return;
707 }
708
709 my_trade->SetItem(TradeSlots(tradeSlot), item);
710}
bool HasItem(ObjectGuid itemGuid) const
Definition: TradeData.cpp:31

◆ HandleSetWatchedFactionOpcode()

void WorldSession::HandleSetWatchedFactionOpcode ( WorldPacket recvData)

Definition at line 1298 of file CharacterHandler.cpp.

1299{
1300 LOG_DEBUG("network.opcode", "WORLD: Received CMSG_SET_WATCHED_FACTION");
1301 uint32 fact;
1302 recvData >> fact;
1304}
@ PLAYER_FIELD_WATCHED_FACTION_INDEX
Definition: UpdateFields.h:379

◆ HandleShowingCloakOpcode()

void WorldSession::HandleShowingCloakOpcode ( WorldPackets::Character::ShowingCloak packet)

◆ HandleShowingHelmOpcode()

void WorldSession::HandleShowingHelmOpcode ( WorldPackets::Character::ShowingHelm packet)

◆ HandleSocketClosed()

bool WorldSession::HandleSocketClosed ( )

Definition at line 502 of file WorldSession.cpp.

503{
504 if (m_Socket && !m_Socket->IsOpen() && !IsKicked() && GetPlayer() && !PlayerLogout() && GetPlayer()->m_taxi.empty() && GetPlayer()->IsInWorld() && !World::IsStopped())
505 {
506 m_Socket = nullptr;
507 GetPlayer()->TradeCancel(false);
508 return true;
509 }
510
511 return false;
512}
bool PlayerLogout() const
Definition: WorldSession.h:336
bool IsKicked() const
static bool IsStopped()
Definition: World.h:263

◆ HandleSocketOpcode()

void WorldSession::HandleSocketOpcode ( WorldPacket recvData)

Definition at line 1351 of file ItemHandler.cpp.

1352{
1353 LOG_DEBUG("network", "WORLD: CMSG_SOCKET_GEMS");
1354
1355 ObjectGuid item_guid;
1356 ObjectGuid gem_guids[MAX_GEM_SOCKETS];
1357
1358 recvData >> item_guid;
1359 if (!item_guid)
1360 return;
1361
1362 for (int i = 0; i < MAX_GEM_SOCKETS; ++i)
1363 recvData >> gem_guids[i];
1364
1365 //cheat -> tried to socket same gem multiple times
1366 if ((gem_guids[0] && (gem_guids[0] == gem_guids[1] || gem_guids[0] == gem_guids[2])) ||
1367 (gem_guids[1] && (gem_guids[1] == gem_guids[2])))
1368 return;
1369
1370 Item* itemTarget = _player->GetItemByGuid(item_guid);
1371 if (!itemTarget) //missing item to socket
1372 return;
1373
1374 ItemTemplate const* itemProto = itemTarget->GetTemplate();
1375 if (!itemProto)
1376 return;
1377
1378 //this slot is excepted when applying / removing meta gem bonus
1379 uint8 slot = itemTarget->IsEquipped() ? itemTarget->GetSlot() : uint8(NULL_SLOT);
1380
1381 Item* Gems[MAX_GEM_SOCKETS];
1382 for (int i = 0; i < MAX_GEM_SOCKETS; ++i)
1383 Gems[i] = gem_guids[i] ? _player->GetItemByGuid(gem_guids[i]) : nullptr;
1384
1385 GemPropertiesEntry const* GemProps[MAX_GEM_SOCKETS];
1386 for (int i = 0; i < MAX_GEM_SOCKETS; ++i) //get geminfo from dbc storage
1387 GemProps[i] = (Gems[i]) ? sGemPropertiesStore.LookupEntry(Gems[i]->GetTemplate()->GemProperties) : nullptr;
1388
1389 // Find first prismatic socket
1390 int32 firstPrismatic = 0;
1391 while (firstPrismatic < MAX_GEM_SOCKETS && itemProto->Socket[firstPrismatic].Color)
1392 ++firstPrismatic;
1393
1394 for (int i = 0; i < MAX_GEM_SOCKETS; ++i) //check for hack maybe
1395 {
1396 if (!GemProps[i])
1397 continue;
1398
1399 // tried to put gem in socket where no socket exists (take care about prismatic sockets)
1400 if (!itemProto->Socket[i].Color)
1401 {
1402 // no prismatic socket
1404 return;
1405
1406 if (i != firstPrismatic)
1407 return;
1408 }
1409
1410 // tried to put normal gem in meta socket
1411 if (itemProto->Socket[i].Color == SOCKET_COLOR_META && GemProps[i]->color != SOCKET_COLOR_META)
1412 return;
1413
1414 // tried to put meta gem in normal socket
1415 if (itemProto->Socket[i].Color != SOCKET_COLOR_META && GemProps[i]->color == SOCKET_COLOR_META)
1416 return;
1417 }
1418
1419 uint32 GemEnchants[MAX_GEM_SOCKETS];
1420 uint32 OldEnchants[MAX_GEM_SOCKETS];
1421 for (int i = 0; i < MAX_GEM_SOCKETS; ++i) //get new and old enchantments
1422 {
1423 GemEnchants[i] = (GemProps[i]) ? GemProps[i]->spellitemenchantement : 0;
1424 OldEnchants[i] = itemTarget->GetEnchantmentId(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT + i));
1425 }
1426
1427 // check unique-equipped conditions
1428 for (int i = 0; i < MAX_GEM_SOCKETS; ++i)
1429 {
1430 if (!Gems[i])
1431 continue;
1432
1433 // continue check for case when attempt add 2 similar unique equipped gems in one item.
1434 ItemTemplate const* iGemProto = Gems[i]->GetTemplate();
1435
1436 // unique item (for new and already placed bit removed enchantments
1437 if (iGemProto->Flags & ITEM_FLAG_UNIQUE_EQUIPPABLE)
1438 {
1439 for (int j = 0; j < MAX_GEM_SOCKETS; ++j)
1440 {
1441 if (i == j) // skip self
1442 continue;
1443
1444 if (Gems[j])
1445 {
1446 if (iGemProto->ItemId == Gems[j]->GetEntry())
1447 {
1449 return;
1450 }
1451 }
1452 else if (OldEnchants[j])
1453 {
1454 if (SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(OldEnchants[j]))
1455 {
1456 if (iGemProto->ItemId == enchantEntry->GemID)
1457 {
1459 return;
1460 }
1461 }
1462 }
1463 }
1464 }
1465
1466 // unique limit type item
1467 int32 limit_newcount = 0;
1468 if (iGemProto->ItemLimitCategory)
1469 {
1470 if (ItemLimitCategoryEntry const* limitEntry = sItemLimitCategoryStore.LookupEntry(iGemProto->ItemLimitCategory))
1471 {
1472 // NOTE: limitEntry->mode is not checked because if item has limit then it is applied in equip case
1473 for (int j = 0; j < MAX_GEM_SOCKETS; ++j)
1474 {
1475 if (Gems[j])
1476 {
1477 // new gem
1478 if (iGemProto->ItemLimitCategory == Gems[j]->GetTemplate()->ItemLimitCategory)
1479 ++limit_newcount;
1480 }
1481 else if (OldEnchants[j])
1482 {
1483 // existing gem
1484 if (SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(OldEnchants[j]))
1485 if (ItemTemplate const* jProto = sObjectMgr->GetItemTemplate(enchantEntry->GemID))
1486 if (iGemProto->ItemLimitCategory == jProto->ItemLimitCategory)
1487 ++limit_newcount;
1488 }
1489 }
1490
1491 if (limit_newcount > 0 && uint32(limit_newcount) > limitEntry->maxCount)
1492 {
1494 return;
1495 }
1496 }
1497 }
1498
1499 // for equipped item check all equipment for duplicate equipped gems
1500 if (itemTarget->IsEquipped())
1501 {
1502 if (InventoryResult res = _player->CanEquipUniqueItem(Gems[i], slot, std::max(limit_newcount, 0)))
1503 {
1504 _player->SendEquipError(res, itemTarget, nullptr);
1505 return;
1506 }
1507 }
1508 }
1509
1510 bool SocketBonusActivated = itemTarget->GemsFitSockets(); //save state of socketbonus
1511 _player->ToggleMetaGemsActive(slot, false); //turn off all metagems (except for the target item)
1512
1513 //if a meta gem is being equipped, all information has to be written to the item before testing if the conditions for the gem are met
1514
1515 //remove ALL enchants
1516 for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT + MAX_GEM_SOCKETS; ++enchant_slot)
1517 _player->ApplyEnchantment(itemTarget, EnchantmentSlot(enchant_slot), false);
1518
1519 for (int i = 0; i < MAX_GEM_SOCKETS; ++i)
1520 {
1521 if (GemEnchants[i])
1522 {
1523 itemTarget->SetEnchantment(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT + i), GemEnchants[i], 0, 0, _player->GetGUID());
1524 if (Item* guidItem = _player->GetItemByGuid(gem_guids[i]))
1525 _player->DestroyItem(guidItem->GetBagSlot(), guidItem->GetSlot(), true);
1526 }
1527 }
1528
1529 for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT + MAX_GEM_SOCKETS; ++enchant_slot)
1530 _player->ApplyEnchantment(itemTarget, EnchantmentSlot(enchant_slot), true);
1531
1532 bool SocketBonusToBeActivated = itemTarget->GemsFitSockets();//current socketbonus state
1533 if (SocketBonusActivated ^ SocketBonusToBeActivated) //if there was a change...
1534 {
1535 _player->ApplyEnchantment(itemTarget, BONUS_ENCHANTMENT_SLOT, false);
1536 itemTarget->SetEnchantment(BONUS_ENCHANTMENT_SLOT, (SocketBonusToBeActivated ? itemTarget->GetTemplate()->socketBonus : 0), 0, 0, _player->GetGUID());
1538 //it is not displayed, client has an inbuilt system to determine if the bonus is activated
1539 }
1540
1541 _player->ToggleMetaGemsActive(slot, true); //turn on all metagems (except for target item)
1542
1543 _player->RemoveTradeableItem(itemTarget);
1544 itemTarget->ClearSoulboundTradeable(_player); // clear tradeable flag
1545
1546 itemTarget->SendUpdateSockets();
1547}
DBCStorage< SpellItemEnchantmentEntry > sSpellItemEnchantmentStore(SpellItemEnchantmentfmt)
DBCStorage< ItemLimitCategoryEntry > sItemLimitCategoryStore(ItemLimitCategoryEntryfmt)
DBCStorage< GemPropertiesEntry > sGemPropertiesStore(GemPropertiesEntryfmt)
#define MAX_GEM_SOCKETS
Definition: Item.h:182
@ PRISMATIC_ENCHANTMENT_SLOT
Definition: Item.h:169
@ SOCK_ENCHANTMENT_SLOT
Definition: Item.h:165
@ BONUS_ENCHANTMENT_SLOT
Definition: Item.h:168
@ EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED
Definition: Item.h:116
@ ITEM_FLAG_UNIQUE_EQUIPPABLE
Definition: ItemTemplate.h:167
@ SOCKET_COLOR_META
Definition: ItemTemplate.h:255
bool GemsFitSockets() const
Definition: Item.cpp:972
void SendUpdateSockets()
Definition: Item.cpp:1064
void ClearSoulboundTradeable(Player *currentOwner)
Definition: Item.cpp:1266
void SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges, ObjectGuid caster=ObjectGuid::Empty)
Definition: Item.cpp:922
void ToggleMetaGemsActive(uint8 exceptslot, bool apply)
Definition: Player.cpp:10991
InventoryResult CanEquipUniqueItem(Item *pItem, uint8 except_slot=NULL_SLOT, uint32 limit_count=1) const
Definition: Player.cpp:13475
void RemoveTradeableItem(Item *item)
Definition: Socket.h:39

◆ HandleSpellClick()

void WorldSession::HandleSpellClick ( WorldPacket recvData)

Definition at line 643 of file SpellHandler.cpp.

644{
645 ObjectGuid guid;
646 recvData >> guid;
647
648 // this will get something not in world. crash
650
651 if (!unit)
652 return;
653
654 // TODO: Unit::SetCharmedBy: 28782 is not in world but 0 is trying to charm it! -> crash
655 if (!unit->IsInWorld())
656 return;
657
659}
bool HandleSpellClick(Unit *clicker, int8 seatId=-1)
Definition: Unit.cpp:19566

◆ HandleSpiritHealerActivateOpcode()

void WorldSession::HandleSpiritHealerActivateOpcode ( WorldPacket recvPacket)

Definition at line 372 of file NPCHandler.cpp.

373{
374 LOG_DEBUG("network", "WORLD: CMSG_SPIRIT_HEALER_ACTIVATE");
375
376 ObjectGuid guid;
377
378 recvData >> guid;
379
381 if (!unit)
382 {
383 LOG_DEBUG("network", "WORLD: HandleSpiritHealerActivateOpcode - Unit ({}) not found or you can not interact with him.", guid.ToString());
384 return;
385 }
386
387 // remove fake death
388 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
390
392}
@ UNIT_NPC_FLAG_SPIRITHEALER
Definition: Unit.h:530
void SendSpiritResurrect()
Definition: NPCHandler.cpp:394

◆ HandleSplitItemOpcode()

void WorldSession::HandleSplitItemOpcode ( WorldPacket recvPacket)

Definition at line 32 of file ItemHandler.cpp.

33{
34 //LOG_DEBUG("network.opcode", "WORLD: CMSG_SPLIT_ITEM");
35 uint8 srcbag, srcslot, dstbag, dstslot;
36 uint32 count;
37
38 recvData >> srcbag >> srcslot >> dstbag >> dstslot >> count;
39
40 uint16 src = ((srcbag << 8) | srcslot);
41 uint16 dst = ((dstbag << 8) | dstslot);
42
43 if (src == dst)
44 return;
45
46 if (count == 0)
47 return; //check count - if zero it's fake packet
48
49 if (!_player->IsValidPos(srcbag, srcslot, true))
50 {
52 return;
53 }
54
55 if (!_player->IsValidPos(dstbag, dstslot, false)) // can be autostore pos
56 {
58 return;
59 }
60
61 _player->SplitItem(src, dst, count);
62}
void SplitItem(uint16 src, uint16 dst, uint32 count)

◆ HandleStablePet()

void WorldSession::HandleStablePet ( WorldPacket recvPacket)

Definition at line 557 of file NPCHandler.cpp.

558{
559 LOG_DEBUG("network", "WORLD: Recv CMSG_STABLE_PET");
560 ObjectGuid npcGUID;
561
562 recvData >> npcGUID;
563
564 if (!GetPlayer()->IsAlive())
565 {
567 return;
568 }
569
570 if (!CheckStableMaster(npcGUID))
571 {
573 return;
574 }
575
576 // remove fake death
577 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
579
580 PetStable* petStable = GetPlayer()->GetPetStable();
581 if (!petStable)
582 return;
583
584 Pet* pet = _player->GetPet();
585
586 // can't place in stable dead pet
587 if ((pet && (!pet->IsAlive() || pet->getPetType() != HUNTER_PET))
588 || (!pet && (petStable->UnslottedPets.size() != 1 || !petStable->UnslottedPets[0].Health || petStable->UnslottedPets[0].Type != HUNTER_PET)))
589 {
591 return;
592 }
593
594 for (uint32 freeSlot = 0; freeSlot < petStable->MaxStabledPets; ++freeSlot)
595 {
596 if (!petStable->StabledPets[freeSlot])
597 {
598 if (pet)
599 {
600 // stable summoned pet
602 std::swap(petStable->StabledPets[freeSlot], petStable->CurrentPet);
604 return;
605 }
606
608 stmt->SetData(0, PetSaveMode(PET_SAVE_FIRST_STABLE_SLOT + freeSlot));
609 stmt->SetData(1, _player->GetGUID().GetCounter());
610 stmt->SetData(2, petStable->UnslottedPets[0].PetNumber);
611 CharacterDatabase.Execute(stmt);
612
613 // stable unsummoned pet
614 petStable->StabledPets[freeSlot] = std::move(petStable->UnslottedPets.back());
615 petStable->UnslottedPets.pop_back();
617 return;
618 }
619 }
620
621 // not free stable slot
623}
@ CHAR_UPD_CHAR_PET_SLOT_BY_ID
PetSaveMode
Definition: PetDefines.h:40
@ PET_SAVE_FIRST_STABLE_SLOT
Definition: PetDefines.h:43
@ STABLE_SUCCESS_STABLE
Definition: NPCHandler.cpp:40
std::array< Optional< PetInfo >, MAX_PET_STABLES > StabledPets
Definition: PetDefines.h:221
std::vector< PetInfo > UnslottedPets
Definition: PetDefines.h:223

◆ HandleStableRevivePet()

void WorldSession::HandleStableRevivePet ( WorldPacket recvPacket)

Definition at line 773 of file NPCHandler.cpp.

774{
775 LOG_DEBUG("network", "HandleStableRevivePet: Not implemented");
776}

◆ HandleStableSwapPet()

void WorldSession::HandleStableSwapPet ( WorldPacket recvPacket)

Definition at line 778 of file NPCHandler.cpp.

779{
780 LOG_DEBUG("network", "WORLD: Recv CMSG_STABLE_SWAP_PET.");
781 ObjectGuid npcGUID;
782 uint32 petId;
783
784 recvData >> npcGUID >> petId;
785
786 if (!CheckStableMaster(npcGUID))
787 {
789 return;
790 }
791
792 // remove fake death
793 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
795
796 PetStable* petStable = GetPlayer()->GetPetStable();
797 if (!petStable)
798 {
800 return;
801 }
802
803 // Find swapped pet slot in stable
804 auto stabledPet = std::find_if(petStable->StabledPets.begin(), petStable->StabledPets.end(), [petId](Optional<PetStable::PetInfo> const& pet)
805 {
806 return pet && pet->PetNumber == petId;
807 });
808
809 if (stabledPet == petStable->StabledPets.end())
810 {
812 return;
813 }
814
815 CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate((*stabledPet)->CreatureId);
816 if (!creatureInfo || !creatureInfo->IsTameable(_player->CanTameExoticPets()))
817 {
818 // if problem in exotic pet
819 if (creatureInfo && creatureInfo->IsTameable(true))
821 else
823 return;
824 }
825
826 Pet* oldPet = _player->GetPet();
827 if (oldPet)
828 {
829 if (!oldPet->IsAlive() || !oldPet->IsHunterPet())
830 {
832 return;
833 }
834
835 _player->RemovePet(oldPet, PetSaveMode(PET_SAVE_FIRST_STABLE_SLOT + std::distance(petStable->StabledPets.begin(), stabledPet)));
836 }
837 else if (petStable->UnslottedPets.size() == 1)
838 {
839 if (petStable->CurrentPet || !petStable->UnslottedPets[0].Health || petStable->UnslottedPets[0].Type != HUNTER_PET)
840 {
842 return;
843 }
844
846 stmt->SetData(0, PetSaveMode(PET_SAVE_FIRST_STABLE_SLOT + std::distance(petStable->StabledPets.begin(), stabledPet)));
847 stmt->SetData(1, _player->GetGUID().GetCounter());
848 stmt->SetData(2, petStable->UnslottedPets[0].PetNumber);
849 CharacterDatabase.Execute(stmt);
850
851 // move unsummoned pet into CurrentPet slot so that it gets moved into stable slot later
852 petStable->CurrentPet = std::move(petStable->UnslottedPets.back());
853 petStable->UnslottedPets.pop_back();
854 }
855 else if (petStable->CurrentPet || !petStable->UnslottedPets.empty())
856 {
858 return;
859 }
860
861 // summon unstabled pet
862 Pet* newPet = new Pet(_player, HUNTER_PET);
863 if (!newPet->LoadPetFromDB(_player, 0, petId, false))
864 {
865 delete newPet;
867
868 petStable->UnslottedPets.push_back(std::move(*petStable->CurrentPet));
869 petStable->CurrentPet.reset();
870
871 // update current pet slot in db immediately to maintain slot consistency, dismissed pet was already saved
874 stmt->SetData(1, _player->GetGUID().GetCounter());
875 stmt->SetData(2, petId);
876 CharacterDatabase.Execute(stmt);
877 }
878 else
879 {
880 // update current pet slot in db immediately to maintain slot consistency, dismissed pet was already saved
883 stmt->SetData(1, _player->GetGUID().GetCounter());
884 stmt->SetData(2, petId);
885 CharacterDatabase.Execute(stmt);
886
888 }
889}
@ STABLE_ERR_EXOTIC
Definition: NPCHandler.cpp:43
@ STABLE_SUCCESS_UNSTABLE
Definition: NPCHandler.cpp:41
bool IsTameable(bool exotic) const
Definition: CreatureData.h:263
bool LoadPetFromDB(Player *owner, uint32 petEntry, uint32 petnumber, bool current, uint32 healthPct=0)
Definition: Pet.cpp:207
bool CanTameExoticPets() const
Definition: Player.h:2137
bool IsHunterPet() const
Definition: Unit.h:1414

◆ HandleStandStateChangeOpcode()

void WorldSession::HandleStandStateChangeOpcode ( WorldPacket recvPacket)

Definition at line 568 of file MiscHandler.cpp.

569{
570 uint32 animstate;
571 recv_data >> animstate;
572
573 switch (animstate)
574 {
579 break;
580 default:
581 return;
582 }
583
584 _player->SetStandState(animstate);
585}
@ UNIT_STAND_STATE_SLEEP
Definition: Unit.h:56
@ UNIT_STAND_STATE_KNEEL
Definition: Unit.h:61

◆ HandleSummonResponseOpcode()

void WorldSession::HandleSummonResponseOpcode ( WorldPacket recvData)

Definition at line 825 of file MovementHandler.cpp.

826{
827 if (!_player->IsAlive() || _player->IsInCombat())
828 return;
829
830 ObjectGuid summoner_guid;
831 bool agree;
832 recvData >> summoner_guid;
833 recvData >> agree;
834
835 if (agree && _player->IsSummonAsSpectator())
836 {
837 ChatHandler chc(this);
838 if (Player* summoner = ObjectAccessor::FindPlayer(summoner_guid))
839 ArenaSpectator::HandleSpectatorSpectateCommand(&chc, summoner->GetName().c_str());
840 else
841 chc.PSendSysMessage("Requested player not found.");
842
843 agree = false;
844 }
846 _player->SummonIfPossible(agree, summoner_guid);
847}
AC_GAME_API bool HandleSpectatorSpectateCommand(ChatHandler *handler, std::string const &name)
void SetSummonAsSpectator(bool on)
Definition: Player.h:1081
void SummonIfPossible(bool agree, ObjectGuid summoner_guid)
Definition: Player.cpp:12135
bool IsSummonAsSpectator() const
Definition: Player.cpp:16017

◆ HandleSwapInvItemOpcode()

void WorldSession::HandleSwapInvItemOpcode ( WorldPacket recvPacket)

Definition at line 64 of file ItemHandler.cpp.

65{
66 //LOG_DEBUG("network.opcode", "WORLD: CMSG_SWAP_INV_ITEM");
67 uint8 srcslot, dstslot;
68
69 recvData >> dstslot >> srcslot;
70
71 // prevent attempt swap same item to current position generated by client at special checting sequence
72 if (srcslot == dstslot)
73 return;
74
75 if (!_player->IsValidPos(INVENTORY_SLOT_BAG_0, srcslot, true))
76 {
78 return;
79 }
80
81 if (!_player->IsValidPos(INVENTORY_SLOT_BAG_0, dstslot, true))
82 {
84 return;
85 }
86
88 {
89 //LOG_DEBUG("network", "WORLD: HandleSwapInvItemOpcode - Unit ({}) not found or you can't interact with him.", m_currentBankerGUID.ToString());
90 return;
91 }
92
94 {
95 //LOG_DEBUG("network", "WORLD: HandleSwapInvItemOpcode - Unit ({}) not found or you can't interact with him.", m_currentBankerGUID.ToString());
96 return;
97 }
98
99 uint16 src = ((INVENTORY_SLOT_BAG_0 << 8) | srcslot);
100 uint16 dst = ((INVENTORY_SLOT_BAG_0 << 8) | dstslot);
101
102 _player->SwapItem(src, dst);
103}

◆ HandleSwapItem()

void WorldSession::HandleSwapItem ( WorldPacket recvPacket)

Definition at line 124 of file ItemHandler.cpp.

125{
126 //LOG_DEBUG("network.opcode", "WORLD: CMSG_SWAP_ITEM");
127 uint8 dstbag, dstslot, srcbag, srcslot;
128
129 recvData >> dstbag >> dstslot >> srcbag >> srcslot;
130
131 uint16 src = ((srcbag << 8) | srcslot);
132 uint16 dst = ((dstbag << 8) | dstslot);
133
134 // prevent attempt swap same item to current position generated by client at special checting sequence
135 if (src == dst)
136 return;
137
138 if (!_player->IsValidPos(srcbag, srcslot, true))
139 {
141 return;
142 }
143
144 if (!_player->IsValidPos(dstbag, dstslot, true))
145 {
147 return;
148 }
149
150 if (_player->IsBankPos(srcbag, srcslot) && !CanUseBank())
151 {
152 //LOG_DEBUG("network", "WORLD: HandleSwapItem - Unit ({}) not found or you can't interact with him.", m_currentBankerGUID.ToString());
153 return;
154 }
155
156 if (_player->IsBankPos(dstbag, dstslot) && !CanUseBank())
157 {
158 //LOG_DEBUG("network", "WORLD: HandleSwapItem - Unit ({}) not found or you can't interact with him.", m_currentBankerGUID.ToString());
159 return;
160 }
161
162 _player->SwapItem(src, dst);
163}

◆ HandleTabardVendorActivateOpcode()

void WorldSession::HandleTabardVendorActivateOpcode ( WorldPacket recvPacket)

Definition at line 46 of file NPCHandler.cpp.

47{
48 ObjectGuid guid;
49 recvData >> guid;
50
52 if (!unit)
53 {
54 LOG_DEBUG("network", "WORLD: HandleTabardVendorActivateOpcode - Unit ({}) not found or you can not interact with him.", guid.ToString());
55 return;
56 }
57
58 // remove fake death
59 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
61
63}
void SendTabardVendorActivate(ObjectGuid guid)
Definition: NPCHandler.cpp:65

◆ HandleTalentWipeConfirmOpcode()

void WorldSession::HandleTalentWipeConfirmOpcode ( WorldPacket recvPacket)

Definition at line 59 of file SkillHandler.cpp.

60{
61 LOG_DEBUG("network", "MSG_TALENT_WIPE_CONFIRM");
62 ObjectGuid guid;
63 recvData >> guid;
64
66 if (!unit)
67 {
68 LOG_DEBUG("network", "WORLD: HandleTalentWipeConfirmOpcode - Unit ({}) not found or you can't interact with him.", guid.ToString());
69 return;
70 }
71
73 return;
74
75 // remove fake death
76 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
78
79 if (!(_player->resetTalents()))
80 {
81 WorldPacket data(MSG_TALENT_WIPE_CONFIRM, 8 + 4); //you have not any talent
82 data << uint64(0);
83 data << uint32(0);
84 SendPacket(&data);
85 return;
86 }
87
89 unit->CastSpell(_player, 14867, true); //spell: "Untalent Visual Effect"
90}
@ UNIT_NPC_FLAG_TRAINER
Definition: Unit.h:520
@ MSG_TALENT_WIPE_CONFIRM
Definition: Opcodes.h:712
bool isCanTrainingAndResetTalentsOf(Player *player) const
Definition: Creature.cpp:1214

◆ HandleTaxiNodeStatusQueryOpcode()

void WorldSession::HandleTaxiNodeStatusQueryOpcode ( WorldPacket recvPacket)

Definition at line 28 of file TaxiHandler.cpp.

29{
30 LOG_DEBUG("network", "WORLD: Received CMSG_TAXINODE_STATUS_QUERY");
31
32 ObjectGuid guid;
33
34 recvData >> guid;
35 SendTaxiStatus(guid);
36}
void SendTaxiStatus(ObjectGuid guid)
Definition: TaxiHandler.cpp:38

◆ HandleTaxiQueryAvailableNodes()

void WorldSession::HandleTaxiQueryAvailableNodes ( WorldPacket recvPacket)

Definition at line 62 of file TaxiHandler.cpp.

63{
64 LOG_DEBUG("network", "WORLD: Received CMSG_TAXIQUERYAVAILABLENODES");
65
66 ObjectGuid guid;
67 recvData >> guid;
68
69 // cheating checks
71 if (!unit)
72 {
73 LOG_DEBUG("network", "WORLD: HandleTaxiQueryAvailableNodes - Unit ({}) not found or you can't interact with him.", guid.ToString());
74 return;
75 }
76
77 // remove fake death
78 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
80
81 // unknown taxi node case
82 if (SendLearnNewTaxiNode(unit))
83 return;
84
85 // known taxi node case
86 SendTaxiMenu(unit);
87}
bool SendLearnNewTaxiNode(Creature *unit)
void SendTaxiMenu(Creature *unit)
Definition: TaxiHandler.cpp:89

◆ HandleTeleportTimeout()

void WorldSession::HandleTeleportTimeout ( bool  updateInSessions)

Definition at line 519 of file WorldSession.cpp.

520{
521 // pussywizard: handle teleport ack timeout
522 if (m_Socket && m_Socket->IsOpen() && GetPlayer() && GetPlayer()->IsBeingTeleported())
523 {
524 time_t currTime = GameTime::GetGameTime().count();
525 if (updateInSessions) // session update from World::UpdateSessions
526 {
527 if (GetPlayer()->IsBeingTeleportedFar() && GetPlayer()->GetSemaphoreTeleportFar() + sWorld->getIntConfig(CONFIG_TELEPORT_TIMEOUT_FAR) < currTime)
528 while (GetPlayer() && GetPlayer()->IsBeingTeleportedFar())
530 }
531 else // session update from Map::Update
532 {
533 if (GetPlayer()->IsBeingTeleportedNear() && GetPlayer()->GetSemaphoreTeleportNear() + sWorld->getIntConfig(CONFIG_TELEPORT_TIMEOUT_NEAR) < currTime)
534 while (GetPlayer() && GetPlayer()->IsInWorld() && GetPlayer()->IsBeingTeleportedNear())
535 {
536 Player* plMover = GetPlayer()->m_mover->ToPlayer();
537 if (!plMover)
538 break;
540 pkt << plMover->GetPackGUID();
541 pkt << uint32(0); // flags
542 pkt << uint32(0); // time
544 }
545 }
546 }
547}
@ CONFIG_TELEPORT_TIMEOUT_FAR
Definition: IWorld.h:334
@ CONFIG_TELEPORT_TIMEOUT_NEAR
Definition: IWorld.h:333
void HandleMoveTeleportAck(WorldPacket &recvPacket)

◆ HandleTextEmoteOpcode()

void WorldSession::HandleTextEmoteOpcode ( WorldPacket recvPacket)

Definition at line 719 of file ChatHandler.cpp.

720{
721 if (!GetPlayer()->IsAlive())
722 return;
723
725
726 if (!GetPlayer()->CanSpeak())
727 {
728 std::string timeStr = secsToTimeString(m_muteTime - GameTime::GetGameTime().count());
730 return;
731 }
732
733 if (GetPlayer()->IsSpectator())
734 return;
735
736 uint32 text_emote, emoteNum;
737 ObjectGuid guid;
738
739 recvData >> text_emote;
740 recvData >> emoteNum;
741 recvData >> guid;
742
743 sScriptMgr->OnPlayerTextEmote(GetPlayer(), text_emote, emoteNum, guid);
744
745 EmotesTextEntry const* em = sEmotesTextStore.LookupEntry(text_emote);
746 if (!em)
747 return;
748
749 uint32 emote_anim = em->textid;
750
751 switch (emote_anim)
752 {
754 case EMOTE_STATE_SIT:
757 break;
758 default:
759 // Only allow text-emotes for "dead" entities (feign death included)
760 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
761 break;
762 GetPlayer()->HandleEmoteCommand(emote_anim);
763 break;
764 }
765
766 Unit* unit = ObjectAccessor::GetUnit(*_player, guid);
767
768 CellCoord p = Acore::ComputeCellCoord(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY());
769
770 Cell cell(p);
771 cell.SetNoCreate();
772
773 Acore::EmoteChatBuilder emote_builder(*GetPlayer(), text_emote, emoteNum, unit);
777 cell.Visit(p, message, *GetPlayer()->GetMap(), *GetPlayer(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE));
778
780
781 //Send scripted event call
782 if (unit && unit->GetTypeId() == TYPEID_UNIT && ((Creature*)unit)->AI())
783 ((Creature*)unit)->AI()->ReceiveEmote(GetPlayer(), text_emote);
784}
DBCStorage< EmotesTextEntry > sEmotesTextStore(EmotesTextEntryfmt)
@ CONFIG_LISTEN_RANGE_TEXTEMOTE
Definition: IWorld.h:189
@ ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE
Definition: DBCEnums.h:174
@ EMOTE_STATE_SLEEP
@ EMOTE_STATE_SIT
@ EMOTE_STATE_KNEEL

◆ HandleTimeSyncResp()

void WorldSession::HandleTimeSyncResp ( WorldPacket recvData)

Definition at line 881 of file MovementHandler.cpp.

882{
883 LOG_DEBUG("network", "CMSG_TIME_SYNC_RESP");
884
885 uint32 counter, clientTimestamp;
886 recvData >> counter >> clientTimestamp;
887
888 if (_pendingTimeSyncRequests.count(counter) == 0)
889 return;
890
891 uint32 serverTimeAtSent = _pendingTimeSyncRequests.at(counter);
892 _pendingTimeSyncRequests.erase(counter);
893
894 // time it took for the request to travel to the client, for the client to process it and reply and for response to travel back to the server.
895 // we are going to make 2 assumptions:
896 // 1) we assume that the request processing time equals 0.
897 // 2) we assume that the packet took as much time to travel from server to client than it took to travel from client to server.
898 uint32 roundTripDuration = getMSTimeDiff(serverTimeAtSent, recvData.GetReceivedTime());
899 uint32 lagDelay = roundTripDuration / 2;
900
901 // clockDelta = serverTime - clientTime
902 // where
903 // serverTime: time that was displayed on the clock of the SERVER at the moment when the client processed the SMSG_TIME_SYNC_REQUEST packet.
904 // clientTime: time that was displayed on the clock of the CLIENT at the moment when the client processed the SMSG_TIME_SYNC_REQUEST packet.
905
906 // Once clockDelta has been computed, we can compute the time of an event on server clock when we know the time of that same event on the client clock,
907 // using the following relation:
908 // serverTime = clockDelta + clientTime
909
910 int64 clockDelta = (int64)serverTimeAtSent + (int64)lagDelay - (int64)clientTimestamp;
911 _timeSyncClockDeltaQueue.put(std::pair<int64, uint32>(clockDelta, roundTripDuration));
913}
void put(T item)
TimePoint GetReceivedTime() const
Definition: WorldPacket.h:79
void ComputeNewClockDelta()

◆ HandleTogglePvP()

void WorldSession::HandleTogglePvP ( WorldPacket recvPacket)

Definition at line 498 of file MiscHandler.cpp.

499{
500 // this opcode can be used in two ways: Either set explicit new status or toggle old status
501 if (recv_data.size() == 1)
502 {
503 bool newPvPStatus;
504 recv_data >> newPvPStatus;
506 }
507 else
509
510 if (GetPlayer()->HasPlayerFlag(PLAYER_FLAGS_IN_PVP))
511 GetPlayer()->UpdatePvP(true, true);
512 else if (!GetPlayer()->pvpInfo.IsHostile && GetPlayer()->IsPvP()) // pussywizard: in pvp mode, but doesn't want to be and not in hostile territory, so start timer
513 GetPlayer()->UpdatePvP(true, false);
514
515 //if (OutdoorPvP* pvp = _player->GetOutdoorPvP())
516 // pvp->HandlePlayerActivityChanged(_player);
517}
@ PLAYER_FLAGS
Definition: UpdateFields.h:178
void ApplyModFlag(uint16 index, uint32 flag, bool apply)
Definition: Object.cpp:899
void ToggleFlag(uint16 index, uint32 flag)
Definition: Object.cpp:877

◆ HandleTotemDestroyed()

void WorldSession::HandleTotemDestroyed ( WorldPackets::Totem::TotemDestroyed totemDestroyed)

Definition at line 606 of file SpellHandler.cpp.

607{
608 // ignore for remote control state
609 if (_player->m_mover != _player)
610 return;
611
612 uint8 slotId = totemDestroyed.Slot;
613 slotId += SUMMON_SLOT_TOTEM;
614
615 if (slotId >= MAX_TOTEM_SLOT)
616 return;
617
618 if (!_player->m_SummonSlot[slotId])
619 return;
620
621 Creature* totem = GetPlayer()->GetMap()->GetCreature(_player->m_SummonSlot[slotId]);
622 // Don't unsummon sentry totem
623 if (totem && totem->IsTotem())
624 totem->ToTotem()->UnSummon();
625}
#define SUMMON_SLOT_TOTEM
Definition: Unit.h:1211
#define MAX_TOTEM_SLOT
Definition: Unit.h:1212
void UnSummon(uint32 msTime=0) override
Definition: Totem.cpp:108
Totem * ToTotem()
Definition: Unit.h:2394
bool IsTotem() const
Definition: Unit.h:1415
ObjectGuid m_SummonSlot[MAX_SUMMON_SLOT]
Definition: Unit.h:2065

◆ HandleTrainerBuySpellOpcode()

void WorldSession::HandleTrainerBuySpellOpcode ( WorldPacket recvPacket)

Definition at line 212 of file NPCHandler.cpp.

213{
214 ObjectGuid guid;
215 uint32 spellId = 0;
216
217 recvData >> guid >> spellId;
218 LOG_DEBUG("network", "WORLD: Received CMSG_TRAINER_BUY_SPELL Npc {}, learn spell id is: {}", guid.ToString(), spellId);
219
221 if (!unit)
222 {
223 LOG_DEBUG("network", "WORLD: HandleTrainerBuySpellOpcode - Unit ({}) not found or you can not interact with him.", guid.ToString());
224 return;
225 }
226
227 // remove fake death
228 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
230
231 // check present spell in trainer spell list
232 TrainerSpellData const* trainer_spells = unit->GetTrainerSpells();
233 if (!trainer_spells)
234 return;
235
236 // not found, cheat?
237 TrainerSpell const* trainer_spell = trainer_spells->Find(spellId);
238 if (!trainer_spell)
239 return;
240
241 if (trainer_spell->reqSpell && !_player->HasSpell(trainer_spell->reqSpell))
242 {
243 return;
244 }
245
246 // can't be learn, cheat? Or double learn with lags...
247 if (_player->GetTrainerSpellState(trainer_spell) != TRAINER_SPELL_GREEN)
248 return;
249
250 // apply reputation discount
251 uint32 nSpellCost = uint32(floor(trainer_spell->spellCost * _player->GetReputationPriceDiscount(unit)));
252
253 // check money requirement
254 if (!_player->HasEnoughMoney(nSpellCost))
255 return;
256
257 _player->ModifyMoney(-int32(nSpellCost));
258
259 unit->SendPlaySpellVisual(179); // 53 SpellCastDirected
260 unit->SendPlaySpellImpact(_player->GetGUID(), 362); // 113 EmoteSalute
261
262 // learn explicitly or cast explicitly
263 if (trainer_spell->IsCastable())
264 _player->CastSpell(_player, trainer_spell->spell, true);
265 else
266 _player->learnSpell(spellId);
267
269 data << guid;
270 data << uint32(spellId); // should be same as in packet from client
271 SendPacket(&data);
272}
@ TRAINER_SPELL_GREEN
Definition: Player.h:214
@ SMSG_TRAINER_BUY_SUCCEEDED
Definition: Opcodes.h:465
TrainerSpellData const * GetTrainerSpells() const
Definition: Creature.cpp:3005
bool IsCastable() const
Definition: CreatureData.h:512
uint32 reqSpell
Definition: CreatureData.h:509
uint32 spellCost
Definition: CreatureData.h:504
TrainerSpell const * Find(uint32 spell_id) const
Definition: Creature.cpp:84
void learnSpell(uint32 spellId, bool temporary=false, bool learnFromSkill=false)
Definition: Player.cpp:3222
TrainerSpellState GetTrainerSpellState(TrainerSpell const *trainer_spell) const
Definition: Player.cpp:3828
void SendPlaySpellVisual(uint32 id)
Definition: Unit.cpp:18943
void SendPlaySpellImpact(ObjectGuid guid, uint32 id)
Definition: Unit.cpp:18951

◆ HandleTrainerListOpcode()

void WorldSession::HandleTrainerListOpcode ( WorldPacket recvPacket)

Definition at line 79 of file NPCHandler.cpp.

80{
81 ObjectGuid guid;
82
83 recvData >> guid;
84 SendTrainerList(guid);
85}
void SendTrainerList(ObjectGuid guid)
Definition: NPCHandler.cpp:87

◆ HandleTurnInPetitionOpcode()

void WorldSession::HandleTurnInPetitionOpcode ( WorldPacket recvData)

Definition at line 637 of file PetitionsHandler.cpp.

638{
639 LOG_DEBUG("network", "Received opcode CMSG_TURN_IN_PETITION");
640
641 // Get petition guid from packet
642 WorldPacket data;
643 ObjectGuid petitionGuid;
644
645 recvData >> petitionGuid;
646
647 // Check if player really has the required petition charter
648 Item* item = _player->GetItemByGuid(petitionGuid);
649 if (!item)
650 return;
651
652 LOG_DEBUG("network", "Petition {} turned in by {}", petitionGuid.ToString(), _player->GetGUID().ToString());
653
654 Petition const* petition = sPetitionMgr->GetPetition(petitionGuid);
655 if (!petition)
656 {
657 LOG_ERROR("network.opcode", "Player {} ({}) tried to turn in petition ({}) that is not present in the database",
658 _player->GetName(), _player->GetGUID().ToString(), petitionGuid.ToString());
659 return;
660 }
661
662 ObjectGuid ownerGuid = petition->ownerGuid;
663 uint8 type = petition->petitionType;
664 std::string name = petition->petitionName;
665
666 // Only the petition owner can turn in the petition
667 if (_player->GetGUID() != ownerGuid)
668 return;
669
670 // Petition type (guild/arena) specific checks
671 if (type == GUILD_CHARTER_TYPE)
672 {
673 // Check if player is already in a guild
674 if (_player->GetGuildId())
675 {
678 SendPacket(&data);
679 return;
680 }
681
682 // Check if guild name is already taken
683 if (sGuildMgr->GetGuildByName(name))
684 {
686 return;
687 }
688 }
689 else
690 {
691 // Check for valid arena bracket (2v2, 3v3, 5v5)
692 uint8 slot = ArenaTeam::GetSlotByType(type);
693 if (slot >= MAX_ARENA_SLOT)
694 return;
695
696 // Check if player is already in an arena team
697 if (_player->GetArenaTeamId(slot))
698 {
700 return;
701 }
702
703 // Check if arena team name is already taken
704 if (sArenaTeamMgr->GetArenaTeamByName(name))
705 {
707 return;
708 }
709 }
710
711 // Get petition signatures from db
712 Signatures const* signatures = sPetitionMgr->GetSignature(petitionGuid);
713 uint8 signs = signatures ? signatures->signatureMap.size() : 0;
714 SignatureMap signatureCopy;
715 if (signs)
716 signatureCopy = signatures->signatureMap;
717
718 uint32 requiredSignatures;
719 if (type == GUILD_CHARTER_TYPE)
720 requiredSignatures = sWorld->getIntConfig(CONFIG_MIN_PETITION_SIGNS);
721 else
722 requiredSignatures = type - 1;
723
724 // Notify player if signatures are missing
725 if (signs < requiredSignatures)
726 {
729 SendPacket(&data);
730 return;
731 }
732
733 // Proceed with guild/arena team creation
734
735 // Delete charter item
736 _player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true);
737
738 if (type == GUILD_CHARTER_TYPE)
739 {
740 // Create guild
741 Guild* guild = new Guild;
742
743 if (!guild->Create(_player, name))
744 {
745 delete guild;
746 return;
747 }
748
749 // Register guild and add guild master
750 sGuildMgr->AddGuild(guild);
751
753
754 // Add members from signatures
755 if (signs)
756 for (SignatureMap::const_iterator itr = signatureCopy.begin(); itr != signatureCopy.end(); ++itr)
757 guild->AddMember(itr->first);
758 }
759 else
760 {
761 // Receive the rest of the packet in arena team creation case
762 uint32 background, icon, iconcolor, border, bordercolor;
763 recvData >> background >> icon >> iconcolor >> border >> bordercolor;
764
765 // Create arena team
766 ArenaTeam* arenaTeam = new ArenaTeam();
767
768 if (!arenaTeam->Create(_player->GetGUID(), type, name, background, icon, iconcolor, border, bordercolor))
769 {
770 delete arenaTeam;
771 return;
772 }
773
774 // Register arena team
775 sArenaTeamMgr->AddArenaTeam(arenaTeam);
776 LOG_DEBUG("network", "PetitonsHandler: Arena team (guid: {}) added to ObjectMgr", arenaTeam->GetId());
777
778 // Add members
779 if (signs)
780 for (SignatureMap::const_iterator itr = signatureCopy.begin(); itr != signatureCopy.end(); ++itr)
781 {
782 LOG_DEBUG("network", "PetitionsHandler: Adding arena team (guid: {}) member {}", arenaTeam->GetId(), itr->first.ToString());
783 arenaTeam->AddMember(itr->first);
784 }
785 }
786
787 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
788
790 stmt->SetData(0, petitionGuid.GetCounter());
791 trans->Append(stmt);
792
793 stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PETITION_SIGNATURE_BY_GUID);
794 stmt->SetData(0, petitionGuid.GetCounter());
795 trans->Append(stmt);
796
797 CharacterDatabase.CommitTransaction(trans);
798
799 // xinef: clear petition store (petition and signatures)
800 sPetitionMgr->RemovePetition(petitionGuid);
801
802 // created
803 LOG_DEBUG("network", "TURN IN PETITION {}", petitionGuid.ToString());
804
806 data << (uint32)PETITION_TURN_OK;
807 SendPacket(&data);
808}
@ CHAR_DEL_PETITION_BY_GUID
@ CHAR_DEL_PETITION_SIGNATURE_BY_GUID
@ ERR_GUILD_COMMAND_SUCCESS
Definition: Guild.h:122
@ PETITION_TURN_NEED_MORE_SIGNATURES
Definition: Guild.h:176
@ PETITION_TURN_ALREADY_IN_GUILD
Definition: Guild.h:175
@ PETITION_TURN_OK
Definition: Guild.h:174
std::map< ObjectGuid, uint32 > SignatureMap
Definition: PetitionMgr.h:37
@ CONFIG_MIN_PETITION_SIGNS
Definition: IWorld.h:246
@ SMSG_TURN_IN_PETITION_RESULTS
Definition: Opcodes.h:483
bool Create(ObjectGuid captainGuid, uint8 type, std::string const &teamName, uint32 backgroundColor, uint8 emblemStyle, uint32 emblemColor, uint8 borderStyle, uint32 borderColor)
Definition: ArenaTeam.cpp:47
bool Create(Player *pLeader, std::string_view name)
Definition: Guild.cpp:1046
bool AddMember(ObjectGuid guid, uint8 rankId=GUILD_RANK_NONE)
Definition: Guild.cpp:2150
std::string petitionName
Definition: PetitionMgr.h:44

◆ HandleTutorialClear()

void WorldSession::HandleTutorialClear ( WorldPacket recvData)

Definition at line 1286 of file CharacterHandler.cpp.

1287{
1288 for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
1289 SetTutorialInt(i, 0xFFFFFFFF);
1290}
#define MAX_ACCOUNT_TUTORIAL_VALUES
Definition: Common.h:91
void SetTutorialInt(uint8 index, uint32 value)
Definition: WorldSession.h:457

◆ HandleTutorialFlag()

void WorldSession::HandleTutorialFlag ( WorldPacket recvData)

Definition at line 1270 of file CharacterHandler.cpp.

1271{
1272 uint32 data;
1273 recvData >> data;
1274
1275 uint8 index = uint8(data / 32);
1276 if (index >= MAX_ACCOUNT_TUTORIAL_VALUES)
1277 return;
1278
1279 uint32 value = (data % 32);
1280
1281 uint32 flag = GetTutorialInt(index);
1282 flag |= (1 << value);
1283 SetTutorialInt(index, flag);
1284}
uint32 GetTutorialInt(uint8 index) const
Definition: WorldSession.h:456

◆ HandleTutorialReset()

void WorldSession::HandleTutorialReset ( WorldPacket recvData)

Definition at line 1292 of file CharacterHandler.cpp.

1293{
1294 for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
1295 SetTutorialInt(i, 0x00000000);
1296}

◆ HandleUnacceptTradeOpcode()

void WorldSession::HandleUnacceptTradeOpcode ( WorldPacket recvPacket)

Definition at line 509 of file TradeHandler.cpp.

510{
511 TradeData* my_trade = _player->GetTradeData();
512 if (!my_trade)
513 return;
514
515 my_trade->SetAccepted(false, true);
516}

◆ HandleUnlearnSkillOpcode()

void WorldSession::HandleUnlearnSkillOpcode ( WorldPacket recvPacket)

Definition at line 92 of file SkillHandler.cpp.

93{
94 uint32 skillId;
95 recvData >> skillId;
96
97 if (!IsPrimaryProfessionSkill(skillId))
98 return;
99
100 GetPlayer()->SetSkill(skillId, 0, 0, 0);
101}
bool IsPrimaryProfessionSkill(uint32 skill)
Definition: SpellMgr.cpp:37
void SetSkill(uint16 id, uint16 step, uint16 currVal, uint16 maxVal)
Definition: Player.cpp:5215

◆ HandleUnstablePet()

void WorldSession::HandleUnstablePet ( WorldPacket recvPacket)

Definition at line 625 of file NPCHandler.cpp.

626{
627 LOG_DEBUG("network", "WORLD: Recv CMSG_UNSTABLE_PET.");
628 ObjectGuid npcGUID;
629 uint32 petnumber;
630
631 recvData >> npcGUID >> petnumber;
632
633 if (!CheckStableMaster(npcGUID))
634 {
636 return;
637 }
638
639 // remove fake death
640 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
642
643 PetStable* petStable = GetPlayer()->GetPetStable();
644 if (!petStable)
645 {
647 return;
648 }
649
650 auto stabledPet = std::find_if(petStable->StabledPets.begin(), petStable->StabledPets.end(), [petnumber](Optional<PetStable::PetInfo> const& pet)
651 {
652 return pet && pet->PetNumber == petnumber;
653 });
654
655 if (stabledPet == petStable->StabledPets.end())
656 {
658 return;
659 }
660
661 CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate((*stabledPet)->CreatureId);
662 if (!creatureInfo || !creatureInfo->IsTameable(_player->CanTameExoticPets()))
663 {
664 // if problem in exotic pet
665 if (creatureInfo && creatureInfo->IsTameable(true))
667 else
669
670 return;
671 }
672
673 Pet* oldPet = _player->GetPet();
674 if (oldPet)
675 {
676 // try performing a swap, client sends this packet instead of swap when starting from stabled slot
677 if (!oldPet->IsAlive() || !oldPet->IsHunterPet())
678 {
680 return;
681 }
682
683 _player->RemovePet(oldPet, PetSaveMode(PET_SAVE_FIRST_STABLE_SLOT + std::distance(petStable->StabledPets.begin(), stabledPet)));
684 }
685 else if (petStable->UnslottedPets.size() == 1)
686 {
687 if (petStable->CurrentPet || !petStable->UnslottedPets[0].Health || petStable->UnslottedPets[0].Type != HUNTER_PET)
688 {
690 return;
691 }
692
694 stmt->SetData(0, PetSaveMode(PET_SAVE_FIRST_STABLE_SLOT + std::distance(petStable->StabledPets.begin(), stabledPet)));
695 stmt->SetData(1, _player->GetGUID().GetCounter());
696 stmt->SetData(2, petStable->UnslottedPets[0].PetNumber);
697 CharacterDatabase.Execute(stmt);
698
699 // move unsummoned pet into CurrentPet slot so that it gets moved into stable slot later
700 petStable->CurrentPet = std::move(petStable->UnslottedPets.back());
701 petStable->UnslottedPets.pop_back();
702 }
703 else if (petStable->CurrentPet || !petStable->UnslottedPets.empty())
704 {
706 return;
707 }
708
709 Pet* newPet = new Pet(_player, HUNTER_PET);
710 if (!newPet->LoadPetFromDB(_player, 0, petnumber, false))
711 {
712 delete newPet;
713
714 petStable->UnslottedPets.push_back(std::move(*petStable->CurrentPet));
715 petStable->CurrentPet.reset();
716
717 // update current pet slot in db immediately to maintain slot consistency, dismissed pet was already saved
720 stmt->SetData(1, _player->GetGUID().GetCounter());
721 stmt->SetData(2, petnumber);
722 CharacterDatabase.Execute(stmt);
723
725 }
726 else
727 {
728 // update current pet slot in db immediately to maintain slot consistency, dismissed pet was already saved
731 stmt->SetData(1, _player->GetGUID().GetCounter());
732 stmt->SetData(2, petnumber);
733 CharacterDatabase.Execute(stmt);
734
736 }
737}

◆ HandleUpdateAccountData()

void WorldSession::HandleUpdateAccountData ( WorldPacket recvPacket)

Definition at line 845 of file MiscHandler.cpp.

846{
847 LOG_DEBUG("network", "WORLD: Received CMSG_UPDATE_ACCOUNT_DATA");
848
849 uint32 type, timestamp, decompressedSize;
850 recv_data >> type >> timestamp >> decompressedSize;
851
852 LOG_DEBUG("network", "UAD: type {}, time {}, decompressedSize {}", type, timestamp, decompressedSize);
853
854 if (type > NUM_ACCOUNT_DATA_TYPES)
855 return;
856
857 if (decompressedSize == 0) // erase
858 {
859 SetAccountData(AccountDataType(type), 0, "");
860
862 data << uint32(type);
863 data << uint32(0);
864 SendPacket(&data);
865
866 return;
867 }
868
869 if (decompressedSize > 0xFFFF)
870 {
871 recv_data.rfinish(); // unnneded warning spam in this case
872 LOG_ERROR("network.opcode", "UAD: Account data packet too big, size {}", decompressedSize);
873 return;
874 }
875
876 ByteBuffer dest;
877 dest.resize(decompressedSize);
878
879 uLongf realSize = decompressedSize;
880 if (uncompress(dest.contents(), &realSize, recv_data.contents() + recv_data.rpos(), recv_data.size() - recv_data.rpos()) != Z_OK)
881 {
882 recv_data.rfinish(); // unnneded warning spam in this case
883 LOG_ERROR("network.opcode", "UAD: Failed to decompress account data");
884 return;
885 }
886
887 recv_data.rfinish(); // uncompress read (recv_data.size() - recv_data.rpos())
888
889 std::string adata;
890 dest >> adata;
891
892 SetAccountData(AccountDataType(type), timestamp, adata);
893
895 data << uint32(type);
896 data << uint32(0);
897 SendPacket(&data);
898}
@ SMSG_UPDATE_ACCOUNT_DATA_COMPLETE
Definition: Opcodes.h:1153
void SetAccountData(AccountDataType type, time_t tm, std::string const &data)

◆ HandleUpdateMissileTrajectory()

void WorldSession::HandleUpdateMissileTrajectory ( WorldPacket recvPacket)

Definition at line 1729 of file MiscHandler.cpp.

1730{
1731 LOG_DEBUG("network", "WORLD: CMSG_UPDATE_MISSILE_TRAJECTORY");
1732
1733 ObjectGuid guid;
1734 uint32 spellId;
1735 float elevation, speed;
1736 float curX, curY, curZ;
1737 float targetX, targetY, targetZ;
1738 uint8 moveStop;
1739
1740 recvPacket >> guid >> spellId >> elevation >> speed;
1741 recvPacket >> curX >> curY >> curZ;
1742 recvPacket >> targetX >> targetY >> targetZ;
1743 recvPacket >> moveStop;
1744
1745 Unit* caster = ObjectAccessor::GetUnit(*_player, guid);
1746 Spell* spell = caster ? caster->GetCurrentSpell(CURRENT_GENERIC_SPELL) : nullptr;
1747 if (!spell || spell->m_spellInfo->Id != spellId || !spell->m_targets.HasDst() || !spell->m_targets.HasSrc())
1748 {
1749 recvPacket.rfinish();
1750 return;
1751 }
1752
1753 Position pos = *spell->m_targets.GetSrcPos();
1754 pos.Relocate(curX, curY, curZ);
1755 spell->m_targets.ModSrc(pos);
1756
1757 pos = *spell->m_targets.GetDstPos();
1758 pos.Relocate(targetX, targetY, targetZ);
1759 spell->m_targets.ModDst(pos);
1760
1761 spell->m_targets.SetElevation(elevation);
1762 spell->m_targets.SetSpeed(speed);
1763
1764 if (moveStop)
1765 {
1766 uint32 opcode;
1767 recvPacket >> opcode;
1768 recvPacket.SetOpcode(opcode);
1769 HandleMovementOpcodes(recvPacket);
1770 }
1771}
@ CURRENT_GENERIC_SPELL
Definition: Unit.h:979
void ModDst(Position const &pos)
Definition: Spell.cpp:430
bool HasSrc() const
Definition: Spell.h:164
bool HasDst() const
Definition: Spell.h:165
void ModSrc(Position const &pos)
Definition: Spell.cpp:379
Position const * GetSrcPos() const
Definition: Spell.cpp:356
WorldLocation const * GetDstPos() const
Definition: Spell.cpp:395

◆ HandleUpdateProjectilePosition()

void WorldSession::HandleUpdateProjectilePosition ( WorldPacket recvPacket)

Definition at line 754 of file SpellHandler.cpp.

755{
756 LOG_DEBUG("network", "WORLD: CMSG_UPDATE_PROJECTILE_POSITION");
757
758 ObjectGuid casterGuid;
759 uint32 spellId;
760 uint8 castCount;
761 float x, y, z; // Position of missile hit
762
763 recvPacket >> casterGuid;
764 recvPacket >> spellId;
765 recvPacket >> castCount;
766 recvPacket >> x;
767 recvPacket >> y;
768 recvPacket >> z;
769
770 Unit* caster = ObjectAccessor::GetUnit(*_player, casterGuid);
771 if (!caster)
772 return;
773
774 Spell* spell = caster->FindCurrentSpellBySpellId(spellId);
775 if (!spell || !spell->m_targets.HasDst())
776 return;
777
778 Position pos = *spell->m_targets.GetDstPos();
779 pos.Relocate(x, y, z);
780 spell->m_targets.ModDst(pos);
781
783 data << casterGuid;
784 data << uint8(castCount);
785 data << float(x);
786 data << float(y);
787 data << float(z);
788 caster->SendMessageToSet(&data, true);
789}
@ SMSG_SET_PROJECTILE_POSITION
Definition: Opcodes.h:1245
Spell * FindCurrentSpellBySpellId(uint32 spell_id) const
Definition: Unit.cpp:4072

◆ HandleUseItemOpcode()

void WorldSession::HandleUseItemOpcode ( WorldPacket recvPacket)

Definition at line 59 of file SpellHandler.cpp.

60{
61 // TODO: add targets.read() check
62 Player* pUser = _player;
63
64 // ignore for remote control state
65 if (pUser->m_mover != pUser)
66 return;
67
68 uint8 bagIndex, slot, castFlags;
69 uint8 castCount; // next cast if exists (single or not)
70 ObjectGuid itemGUID;
71 uint32 glyphIndex; // something to do with glyphs?
72 uint32 spellId; // casted spell id
73
74 recvPacket >> bagIndex >> slot >> castCount >> spellId >> itemGUID >> glyphIndex >> castFlags;
75
76 if (glyphIndex >= MAX_GLYPH_SLOT_INDEX)
77 {
78 pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
79 return;
80 }
81
82 Item* pItem = pUser->GetUseableItemByPos(bagIndex, slot);
83 if (!pItem)
84 {
85 pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
86 return;
87 }
88
89 if (pItem->GetGUID() != itemGUID)
90 {
91 pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
92 return;
93 }
94
95 LOG_DEBUG("network", "WORLD: CMSG_USE_ITEM packet, bagIndex: {}, slot: {}, castCount: {}, spellId: {}, Item: {}, glyphIndex: {}, data length = {}", bagIndex, slot, castCount, spellId, pItem->GetEntry(), glyphIndex, (uint32)recvPacket.size());
96
97 ItemTemplate const* proto = pItem->GetTemplate();
98 if (!proto)
99 {
100 pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, nullptr);
101 return;
102 }
103
104 // some item classes can be used only in equipped state
105 if (proto->InventoryType != INVTYPE_NON_EQUIP && !pItem->IsEquipped())
106 {
107 pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, nullptr);
108 return;
109 }
110
111 InventoryResult msg = pUser->CanUseItem(pItem);
112 if (msg != EQUIP_ERR_OK)
113 {
114 pUser->SendEquipError(msg, pItem, nullptr);
115 return;
116 }
117
118 // only allow conjured consumable, bandage, poisons (all should have the 2^21 item flag set in DB)
120 {
121 pUser->SendEquipError(EQUIP_ERR_NOT_DURING_ARENA_MATCH, pItem, nullptr);
122 return;
123 }
124
125 // don't allow items banned in arena
126 if (proto->Flags & ITEM_FLAG_NOT_USEABLE_IN_ARENA && pUser->InArena())
127 {
128 pUser->SendEquipError(EQUIP_ERR_NOT_DURING_ARENA_MATCH, pItem, nullptr);
129 return;
130 }
131
132 if (pUser->IsInCombat())
133 {
134 for (int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
135 {
136 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(proto->Spells[i].SpellId))
137 {
138 if (!spellInfo->CanBeUsedInCombat())
139 {
140 pUser->SendEquipError(EQUIP_ERR_NOT_IN_COMBAT, pItem, nullptr);
141 return;
142 }
143 }
144 }
145 }
146
147 // check also BIND_WHEN_PICKED_UP and BIND_QUEST_ITEM for .additem or .additemset case by GM (not binded at adding to inventory)
149 {
150 if (!pItem->IsSoulBound())
151 {
152 pItem->SetState(ITEM_CHANGED, pUser);
153 pItem->SetBinding(true);
154 }
155 }
156
157 SpellCastTargets targets;
158 targets.Read(recvPacket, pUser);
159 HandleClientCastFlags(recvPacket, castFlags, targets);
160
161 // Note: If script stop casting it must send appropriate data to client to prevent stuck item in gray state.
162 if (!sScriptMgr->OnItemUse(pUser, pItem, targets))
163 {
164 // no script or script not process request by self
165 pUser->CastItemUseSpell(pItem, targets, castCount, glyphIndex);
166 }
167}
@ EQUIP_ERR_NOT_DURING_ARENA_MATCH
Definition: Item.h:118
@ EQUIP_ERR_NOT_IN_COMBAT
Definition: Item.h:101
@ INVTYPE_NON_EQUIP
Definition: ItemTemplate.h:265
@ ITEM_FLAG_IGNORE_DEFAULT_ARENA_RESTRICTIONS
Definition: ItemTemplate.h:169
@ ITEM_FLAG_NOT_USEABLE_IN_ARENA
Definition: ItemTemplate.h:174
@ BIND_WHEN_USE
Definition: ItemTemplate.h:99
@ BIND_QUEST_ITEM
Definition: ItemTemplate.h:100
@ BIND_WHEN_PICKED_UP
Definition: ItemTemplate.h:97
@ ITEM_CLASS_CONSUMABLE
Definition: ItemTemplate.h:300
void SetBinding(bool val)
Definition: Item.h:229
Item * GetUseableItemByPos(uint8 bag, uint8 slot) const
Definition: Player.h:1220
void CastItemUseSpell(Item *item, SpellCastTargets const &targets, uint8 cast_count, uint32 glyphIndex)
Definition: Player.cpp:7241

◆ HandleVoiceSessionEnableOpcode()

void WorldSession::HandleVoiceSessionEnableOpcode ( WorldPacket recvData)

Definition at line 23 of file VoiceChatHandler.cpp.

24{
25 LOG_DEBUG("network", "WORLD: CMSG_VOICE_SESSION_ENABLE");
26 // uint8 isVoiceEnabled, uint8 isMicrophoneEnabled
27 recvData.read_skip<uint8>();
28 recvData.read_skip<uint8>();
29}

◆ HandleWardenDataOpcode()

void WorldSession::HandleWardenDataOpcode ( WorldPacket recvData)

Definition at line 318 of file Warden.cpp.

319{
320 if (!_warden || recvData.empty())
321 return;
322
323 _warden->DecryptData(recvData.contents(), recvData.size());
324 uint8 opcode;
325 recvData >> opcode;
326 LOG_DEBUG("warden", "Got packet, opcode {:02X}, size {}", opcode, uint32(recvData.size()));
327 recvData.hexlike();
328
329 switch (opcode)
330 {
332 _warden->SendModuleToClient();
333 break;
335 _warden->RequestHash();
336 break;
338 _warden->HandleData(recvData);
339 break;
341 LOG_DEBUG("warden", "NYI WARDEN_CMSG_MEM_CHECKS_RESULT received!");
342 break;
344 _warden->HandleHashResult(recvData);
345 _warden->InitializeModule();
346 break;
348 LOG_DEBUG("warden", "NYI WARDEN_CMSG_MODULE_FAILED received!");
349 break;
350 default:
351 LOG_DEBUG("warden", "Got unknown warden opcode {:02X} of size {}.", opcode, uint32(recvData.size() - 1));
352 break;
353 }
354}
@ WARDEN_CMSG_MODULE_MISSING
Definition: Warden.h:30
@ WARDEN_CMSG_HASH_RESULT
Definition: Warden.h:34
@ WARDEN_CMSG_MODULE_FAILED
Definition: Warden.h:35
@ WARDEN_CMSG_CHEAT_CHECKS_RESULT
Definition: Warden.h:32
@ WARDEN_CMSG_MODULE_OK
Definition: Warden.h:31
@ WARDEN_CMSG_MEM_CHECKS_RESULT
Definition: Warden.h:33
void hexlike() const
Definition: ByteBuffer.cpp:189

◆ HandleWhoisOpcode()

void WorldSession::HandleWhoisOpcode ( WorldPacket recvData)

Definition at line 1119 of file MiscHandler.cpp.

1120{
1121 LOG_DEBUG("network", "Received opcode CMSG_WHOIS");
1122 std::string charname;
1123 recv_data >> charname;
1124
1126 {
1128 return;
1129 }
1130
1131 if (charname.empty() || !normalizePlayerName (charname))
1132 {
1134 return;
1135 }
1136
1137 Player* player = ObjectAccessor::FindPlayerByName(charname, false);
1138
1139 if (!player)
1140 {
1142 return;
1143 }
1144
1145 uint32 accid = player->GetSession()->GetAccountId();
1146
1148
1149 stmt->SetData(0, accid);
1150
1151 PreparedQueryResult result = LoginDatabase.Query(stmt);
1152
1153 if (!result)
1154 {
1156 return;
1157 }
1158
1159 Field* fields = result->Fetch();
1160 std::string acc = fields[0].Get<std::string>();
1161 if (acc.empty())
1162 acc = "Unknown";
1163 std::string email = fields[1].Get<std::string>();
1164 if (email.empty())
1165 email = "Unknown";
1166 std::string lastip = fields[2].Get<std::string>();
1167 if (lastip.empty())
1168 lastip = "Unknown";
1169
1170 std::string msg = charname + "'s " + "account is " + acc + ", e-mail: " + email + ", last ip: " + lastip;
1171
1172 WorldPacket data(SMSG_WHOIS, msg.size() + 1);
1173 data << msg;
1174 SendPacket(&data);
1175
1176 LOG_DEBUG("network", "Received whois command from player {} for character {}", GetPlayer()->GetName(), charname);
1177}
@ LOGIN_SEL_ACCOUNT_WHOIS
Definition: LoginDatabase.h:95
@ LANG_PLAYER_NOT_EXIST_OR_OFFLINE
Definition: Language.h:719
@ LANG_ACCOUNT_FOR_PLAYER_NOT_FOUND
Definition: Language.h:720
@ LANG_YOU_NOT_HAVE_PERMISSION
Definition: Language.h:715
@ LANG_NEED_CHARACTER_NAME
Definition: Language.h:718
@ SMSG_WHOIS
Definition: Opcodes.h:131
bool IsAdminAccount(uint32 gmlevel)
Definition: AccountMgr.cpp:286

◆ HandleWhoOpcode()

void WorldSession::HandleWhoOpcode ( WorldPacket recvPacket)

Definition at line 212 of file MiscHandler.cpp.

213{
214 LOG_DEBUG("network", "WORLD: Recvd CMSG_WHO Message");
215
216 uint32 matchCount = 0;
217
218 uint32 levelMin, levelMax, racemask, classmask, zonesCount, strCount;
219 std::array<uint32, 10> zoneids = {}; // 10 is client limit
220 std::string packetPlayerName, packetGuildName;
221
222 recvData >> levelMin; // maximal player level, default 0
223 recvData >> levelMax; // minimal player level, default 100 (MAX_LEVEL)
224 recvData >> packetPlayerName; // player name, case sensitive...
225
226 recvData >> packetGuildName; // guild name, case sensitive...
227
228 recvData >> racemask; // race mask
229 recvData >> classmask; // class mask
230 recvData >> zonesCount; // zones count, client limit = 10 (2.0.10)
231
232 if (zonesCount > 10)
233 return; // can't be received from real client or broken packet
234
235 for (uint32 i = 0; i < zonesCount; ++i)
236 {
237 uint32 temp;
238 recvData >> temp; // zone id, 0 if zone is unknown...
239 zoneids[i] = temp;
240 LOG_DEBUG("network.who", "Zone {}: {}", i, zoneids[i]);
241 }
242
243 recvData >> strCount; // user entered strings count, client limit=4 (checked on 2.0.10)
244
245 if (strCount > 4)
246 return; // can't be received from real client or broken packet
247
248 LOG_DEBUG("network.who", "Minlvl {}, maxlvl {}, name {}, guild {}, racemask {}, classmask {}, zones {}, strings {}",
249 levelMin, levelMax, packetPlayerName, packetGuildName, racemask, classmask, zonesCount, strCount);
250
251 std::wstring str[4]; // 4 is client limit
252 for (uint32 i = 0; i < strCount; ++i)
253 {
254 std::string temp;
255 recvData >> temp; // user entered string, it used as universal search pattern(guild+player name)?
256
257 if (!Utf8toWStr(temp, str[i]))
258 continue;
259
260 wstrToLower(str[i]);
261
262 LOG_DEBUG("network.who", "String {}: {}", i, temp);
263 }
264
265 std::wstring wpacketPlayerName;
266 std::wstring wpacketGuildName;
267 if (!(Utf8toWStr(packetPlayerName, wpacketPlayerName) && Utf8toWStr(packetGuildName, wpacketGuildName)))
268 return;
269
270 wstrToLower(wpacketPlayerName);
271 wstrToLower(wpacketGuildName);;
272
273 // client send in case not set max level value 100 but Acore supports 255 max level,
274 // update it to show GMs with characters after 100 level
275 if (levelMax >= MAX_LEVEL)
276 levelMax = STRONG_MAX_LEVEL;
277
278 uint32 team = _player->GetTeamId();
279 uint32 security = GetSecurity();
280 bool allowTwoSideWhoList = sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST);
281 uint32 gmLevelInWhoList = sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST);
282 uint32 displaycount = 0;
283
284 WorldPacket data(SMSG_WHO, 50); // guess size
285 data << uint32(matchCount); // placeholder, count of players matching criteria
286 data << uint32(displaycount); // placeholder, count of players displayed
287
288 for (auto const& target : sWhoListCacheMgr->GetWhoList())
289 {
290 if (AccountMgr::IsPlayerAccount(security))
291 {
292 // player can see member of other team only if CONFIG_ALLOW_TWO_SIDE_WHO_LIST
293 if (target.GetTeamId() != team && !allowTwoSideWhoList)
294 {
295 continue;
296 }
297
298 // player can see MODERATOR, GAME MASTER, ADMINISTRATOR only if CONFIG_GM_IN_WHO_LIST
299 if (target.GetSecurity() > AccountTypes(gmLevelInWhoList))
300 {
301 continue;
302 }
303 }
304
305 // check if target is globally visible for player
306 if ((_player->GetGUID() != target.GetGuid() && !target.IsVisible()) &&
308 {
309 continue;
310 }
311
312 // check if target's level is in level range
313 uint8 lvl = target.GetLevel();
314 if (lvl < levelMin || lvl > levelMax)
315 {
316 continue;
317 }
318
319 // check if class matches classmask
320 uint8 class_ = target.GetClass();
321 if (!(classmask & (1 << class_)))
322 {
323 continue;
324 }
325
326 // check if race matches racemask
327 uint32 race = target.GetRace();
328 if (!(racemask & (1 << race)))
329 {
330 continue;
331 }
332
333 uint32 playerZoneId = target.GetZoneId();
334 uint8 gender = target.GetGender();
335
336 bool showZones = true;
337 for (uint32 i = 0; i < zonesCount; ++i)
338 {
339 if (zoneids[i] == playerZoneId)
340 {
341 showZones = true;
342 break;
343 }
344
345 showZones = false;
346 }
347
348 if (!showZones)
349 {
350 continue;
351 }
352
353 std::wstring const& wideplayername = target.GetWidePlayerName();
354 if (!(wpacketPlayerName.empty() || wideplayername.find(wpacketPlayerName) != std::wstring::npos))
355 {
356 continue;
357 }
358
359 std::wstring const& wideguildname = target.GetWideGuildName();
360 if (!(wpacketGuildName.empty() || wideguildname.find(wpacketGuildName) != std::wstring::npos))
361 {
362 continue;
363 }
364
365 std::string aname;
366 if (AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(playerZoneId))
367 {
368 aname = areaEntry->area_name[GetSessionDbcLocale()];
369 }
370
371 bool s_show = true;
372 for (uint32 i = 0; i < strCount; ++i)
373 {
374 if (!str[i].empty())
375 {
376 if (wideguildname.find(str[i]) != std::wstring::npos ||
377 wideplayername.find(str[i]) != std::wstring::npos ||
378 Utf8FitTo(aname, str[i]))
379 {
380 s_show = true;
381 break;
382 }
383
384 s_show = false;
385 }
386 }
387
388 if (!s_show)
389 {
390 continue;
391 }
392
393 // 49 is maximum player count sent to client - can be overridden
394 // through config, but is unstable
395 if ((matchCount++) >= sWorld->getIntConfig(CONFIG_MAX_WHO_LIST_RETURN))
396 {
397 continue;
398 }
399
400 data << target.GetPlayerName(); // player name
401 data << target.GetGuildName(); // guild name
402 data << uint32(lvl); // player level
403 data << uint32(class_); // player class
404 data << uint32(race); // player race
405 data << uint8(gender); // player gender
406 data << uint32(playerZoneId); // player zone id
407
408 ++displaycount;
409 }
410
411 data.put(0, displaycount); // insert right count, count displayed
412 data.put(4, matchCount); // insert right count, count of matches
413
414 SendPacket(&data);
415 LOG_DEBUG("network", "WORLD: Send SMSG_WHO Message");
416}
AccountTypes
Definition: Common.h:65
void wstrToLower(std::wstring &str)
Definition: Util.cpp:383
bool Utf8FitTo(std::string_view str, std::wstring_view search)
Definition: Util.cpp:477
#define sWhoListCacheMgr
@ CONFIG_MAX_WHO_LIST_RETURN
Definition: IWorld.h:389
@ CONFIG_GM_LEVEL_IN_WHO_LIST
Definition: IWorld.h:253
@ CONFIG_ALLOW_TWO_SIDE_WHO_LIST
Definition: IWorld.h:84
#define MAX_LEVEL
Definition: DBCEnums.h:45
#define STRONG_MAX_LEVEL
Definition: DBCEnums.h:49
@ SMSG_WHO
Definition: Opcodes.h:129

◆ HandleWorldStateUITimerUpdate()

void WorldSession::HandleWorldStateUITimerUpdate ( WorldPacket recvData)

Definition at line 1616 of file MiscHandler.cpp.

1617{
1618 // empty opcode
1619 LOG_DEBUG("network", "WORLD: CMSG_WORLD_STATE_UI_TIMER_UPDATE");
1620
1622 response.Time = GameTime::GetGameTime().count();
1623 SendPacket(response.Write());
1624}
WorldPacket const * Write() override

◆ HandleWorldTeleportOpcode()

void WorldSession::HandleWorldTeleportOpcode ( WorldPacket recvData)

Definition at line 1087 of file MiscHandler.cpp.

1088{
1089 uint32 time;
1090 uint32 mapid;
1091 float PositionX;
1092 float PositionY;
1093 float PositionZ;
1094 float Orientation;
1095
1096 recv_data >> time; // time in m.sec.
1097 recv_data >> mapid;
1098 recv_data >> PositionX;
1099 recv_data >> PositionY;
1100 recv_data >> PositionZ;
1101 recv_data >> Orientation; // o (3.141593 = 180 degrees)
1102
1103 LOG_DEBUG("network", "WORLD: Received CMSG_WORLD_TELEPORT");
1104
1105 if (GetPlayer()->IsInFlight())
1106 {
1107 LOG_DEBUG("network", "Player '{}' ({}) in flight, ignore worldport command.", GetPlayer()->GetName(), GetPlayer()->GetGUID().ToString());
1108 return;
1109 }
1110
1111 LOG_DEBUG("network", "CMSG_WORLD_TELEPORT: Player = {}, Time = {}, map = {}, x = {}, y = {}, z = {}, o = {}", GetPlayer()->GetName(), time, mapid, PositionX, PositionY, PositionZ, Orientation);
1112
1114 GetPlayer()->TeleportTo(mapid, PositionX, PositionY, PositionZ, Orientation);
1115 else
1117}

◆ HandleWrapItemOpcode()

void WorldSession::HandleWrapItemOpcode ( WorldPacket recvPacket)

Definition at line 1224 of file ItemHandler.cpp.

1225{
1226 LOG_DEBUG("network", "Received opcode CMSG_WRAP_ITEM");
1227
1228 uint8 gift_bag, gift_slot, item_bag, item_slot;
1229
1230 recvData >> gift_bag >> gift_slot; // paper
1231 recvData >> item_bag >> item_slot; // item
1232
1233 LOG_DEBUG("network", "WRAP: receive gift_bag = {}, gift_slot = {}, item_bag = {}, item_slot = {}", gift_bag, gift_slot, item_bag, item_slot);
1234
1235 Item* gift = _player->GetItemByPos(gift_bag, gift_slot);
1236 if (!gift)
1237 {
1239 return;
1240 }
1241
1242 if (!(gift->GetTemplate()->Flags & ITEM_FLAG_IS_WRAPPER)) // cheating: non-wrapper wrapper
1243 {
1245 return;
1246 }
1247
1248 Item* item = _player->GetItemByPos(item_bag, item_slot);
1249
1250 if (!item)
1251 {
1253 return;
1254 }
1255
1256 // xinef: do not allow to wrap removed items, just in case
1257 if (item->GetState() == ITEM_REMOVED)
1258 {
1260 return;
1261 }
1262
1263 if (item == gift) // not possable with pacjket from real client
1264 {
1266 return;
1267 }
1268
1269 if (item->IsEquipped())
1270 {
1272 return;
1273 }
1274
1275 if (item->GetGuidValue(ITEM_FIELD_GIFTCREATOR)) // HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED);
1276 {
1278 return;
1279 }
1280
1281 if (item->IsBag())
1282 {
1284 return;
1285 }
1286
1287 if (item->IsSoulBound())
1288 {
1290 return;
1291 }
1292
1293 if (item->GetMaxStackCount() != 1)
1294 {
1296 return;
1297 }
1298
1299 // maybe not correct check (it is better than nothing)
1300 if (item->GetTemplate()->MaxCount > 0)
1301 {
1303 return;
1304 }
1305
1306 CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
1307
1309 stmt->SetData(0, item->GetOwnerGUID().GetCounter());
1310 stmt->SetData(1, item->GetGUID().GetCounter());
1311 stmt->SetData(2, item->GetEntry());
1312 stmt->SetData(3, item->GetUInt32Value(ITEM_FIELD_FLAGS));
1313 trans->Append(stmt);
1314
1315 item->SetEntry(gift->GetEntry());
1316
1317 switch (item->GetEntry())
1318 {
1319 case 5042:
1320 item->SetEntry(5043);
1321 break;
1322 case 5048:
1323 item->SetEntry(5044);
1324 break;
1325 case 17303:
1326 item->SetEntry(17302);
1327 break;
1328 case 17304:
1329 item->SetEntry(17305);
1330 break;
1331 case 17307:
1332 item->SetEntry(17308);
1333 break;
1334 case 21830:
1335 item->SetEntry(21831);
1336 break;
1337 }
1341
1342 // after save it will be impossible to remove the item from the queue
1344
1345 CharacterDatabase.CommitTransaction(trans);
1346
1347 uint32 count = 1;
1348 _player->DestroyItemCount(gift, count, true);
1349}
@ CHAR_INS_CHAR_GIFT
@ EQUIP_ERR_BAGS_CANT_BE_WRAPPED
Definition: Item.h:89
@ EQUIP_ERR_STACKABLE_CANT_BE_WRAPPED
Definition: Item.h:84
@ EQUIP_ERR_UNIQUE_CANT_BE_WRAPPED
Definition: Item.h:88
@ EQUIP_ERR_WRAPPED_CANT_BE_WRAPPED
Definition: Item.h:86
@ EQUIP_ERR_BOUND_CANT_BE_WRAPPED
Definition: Item.h:87
@ EQUIP_ERR_EQUIPPED_CANT_BE_WRAPPED
Definition: Item.h:85
@ ITEM_REMOVED
Definition: Item.h:206
@ ITEM_FLAG_IS_WRAPPER
Definition: ItemTemplate.h:157

◆ HandleZoneUpdateOpcode()

void WorldSession::HandleZoneUpdateOpcode ( WorldPacket recvPacket)

Definition at line 519 of file MiscHandler.cpp.

520{
521 uint32 newZone;
522 recv_data >> newZone;
523
524 LOG_DEBUG("network", "WORLD: Recvd ZONE_UPDATE: {}", newZone);
525
526 // use server side data, but only after update the player position. See Player::UpdatePosition().
528
529 //GetPlayer()->SendInitWorldStates(true, newZone);
530}
void SetNeedZoneUpdate(bool needUpdate)
Definition: Player.h:1809

◆ InitWarden()

void WorldSession::InitWarden ( SessionKey const &  k,
std::string const &  os 
)

Definition at line 1290 of file WorldSession.cpp.

1291{
1292 if (os == "Win")
1293 {
1294 _warden = std::make_unique<WardenWin>();
1295 _warden->Init(this, k);
1296 }
1297 else if (os == "OSX")
1298 {
1299 // Disabled as it is causing the client to crash
1300 // _warden = new WardenMac();
1301 // _warden->Init(this, k);
1302 }
1303}

◆ IsARecruiter()

bool WorldSession::IsARecruiter ( ) const
inline

Definition at line 524 of file WorldSession.h.

524{ return isRecruiter; }

◆ IsConnectionIdle()

bool WorldSession::IsConnectionIdle ( ) const
inline

Definition at line 517 of file WorldSession.h.

518 {
519 return (m_timeOutTime <= 0 && !m_inQueue);
520 }

◆ IsKicked()

bool WorldSession::IsKicked ( ) const
inline

Definition at line 1066 of file WorldSession.h.

1066{ return _kicked; }

◆ IsLegitCharacterForAccount()

bool WorldSession::IsLegitCharacterForAccount ( ObjectGuid  guid)
inlineprivate

Definition at line 1130 of file WorldSession.h.

1131 {
1132 return _legitCharacters.find(guid) != _legitCharacters.end();
1133 }

◆ isLogingOut()

bool WorldSession::isLogingOut ( ) const
inline

Is the user engaged in a log out process?

Definition at line 382 of file WorldSession.h.

382{ return _logoutTime || m_playerLogout; }

◆ IsSocketClosed()

bool WorldSession::IsSocketClosed ( ) const

Definition at line 514 of file WorldSession.cpp.

515{
516 return !m_Socket || !m_Socket->IsOpen();
517}

◆ KickPlayer() [1/2]

void WorldSession::KickPlayer ( bool  setKicked = true)
inline

Definition at line 397 of file WorldSession.h.

397{ return this->KickPlayer("Unknown reason", setKicked); }

◆ KickPlayer() [2/2]

void WorldSession::KickPlayer ( std::string const &  reason,
bool  setKicked = true 
)

Kick a player out of the World.

Definition at line 721 of file WorldSession.cpp.

722{
723 if (m_Socket)
724 {
725 LOG_INFO("network.kick", "Account: {} Character: '{}' {} kicked with reason: {}", GetAccountId(), _player ? _player->GetName() : "<none>",
726 _player ? _player->GetGUID().ToString() : "", reason);
727
728 m_Socket->CloseSocket();
729 }
730
731 if (setKicked)
732 SetKicked(true); // pussywizard: the session won't be left ingame for 60 seconds and to also kick offline session
733}
void SetKicked(bool val)

◆ LoadAccountData()

void WorldSession::LoadAccountData ( PreparedQueryResult  result,
uint32  mask 
)

Definition at line 852 of file WorldSession.cpp.

853{
854 for (uint32 i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i)
855 if (mask & (1 << i))
857
858 if (!result)
859 return;
860
861 do
862 {
863 Field* fields = result->Fetch();
864 uint32 type = fields[0].Get<uint8>();
865 if (type >= NUM_ACCOUNT_DATA_TYPES)
866 {
867 LOG_ERROR("network", "Table `{}` have invalid account data type ({}), ignore.", mask == GLOBAL_CACHE_MASK ? "account_data" : "character_account_data", type);
868 continue;
869 }
870
871 if ((mask & (1 << type)) == 0)
872 {
873 LOG_ERROR("network", "Table `{}` have non appropriate for table account data type ({}), ignore.", mask == GLOBAL_CACHE_MASK ? "account_data" : "character_account_data", type);
874 continue;
875 }
876
877 m_accountData[type].Time = time_t(fields[1].Get<uint32>());
878 m_accountData[type].Data = fields[2].Get<std::string>();
879 } while (result->NextRow());
880}

◆ LoadGlobalAccountData()

void WorldSession::LoadGlobalAccountData ( )

Definition at line 845 of file WorldSession.cpp.

846{
848 stmt->SetData(0, GetAccountId());
850}
@ CHAR_SEL_ACCOUNT_DATA

◆ LoadTutorialsData()

void WorldSession::LoadTutorialsData ( )

Definition at line 924 of file WorldSession.cpp.

925{
926 memset(m_Tutorials, 0, sizeof(uint32) * MAX_ACCOUNT_TUTORIAL_VALUES);
927
929 stmt->SetData(0, GetAccountId());
930 if (PreparedQueryResult result = CharacterDatabase.Query(stmt))
931 for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
932 m_Tutorials[i] = (*result)[i].Get<uint32>();
933
934 m_TutorialsChanged = false;
935}
@ CHAR_SEL_TUTORIALS

◆ LogoutPlayer()

void WorldSession::LogoutPlayer ( bool  save)

Log the player out

  • If the player just died before logging out, make him appear as a ghost
  • If the player is in a guild, update the guild roster and broadcast a logout message to other guild members
  • Remove pet
  • If the player is in a group and LeaveGroupOnLogout is enabled or if the player is invited to a group, remove him. If the group is then only 1 person, disband the group.
  • empty buyback items and save the player in the database
  • Leave all channels before player delete...

Send update to group and reset stored max enchanting level

Broadcast a logout message to the player's friends

Call script hook before deletion

Remove the player from the world

Send the 'logout complete' packet to the client Client will respond by sending 3x CMSG_CANCEL_TRADE, which we currently dont handle

Since each account can only have one online character at any given time, ensure all characters for active account are marked as offline

Definition at line 550 of file WorldSession.cpp.

551{
552 // finish pending transfers before starting the logout
555
556 m_playerLogout = true;
557 m_playerSave = save;
558
559 if (_player)
560 {
561 if (ObjectGuid lguid = _player->GetLootGUID())
562 DoLootRelease(lguid);
563
565 //FIXME: logout must be delayed in case lost connection with client in time of combat
566 if (_player->GetDeathTimer())
567 {
571 }
573 {
574 // this will kill character by SPELL_AURA_SPIRIT_OF_REDEMPTION
579 }
580 else if (_player->HasPendingBind())
581 {
583 _player->SetPendingBind(0, 0);
584 }
585
586 // pussywizard: leave whole bg on logout (character stays ingame when necessary)
587 // pussywizard: GetBattleground() checked inside
589
590 // pussywizard: checked first time
593
594 sOutdoorPvPMgr->HandlePlayerLeaveZone(_player, _player->GetZoneId());
595
596 // pussywizard: remove from battleground queues on logout
597 for (int i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i)
599 {
600 // track if player logs out after invited to join BG
602 {
604 {
606 stmt->SetData(0, _player->GetGUID().GetCounter());
608 CharacterDatabase.Execute(stmt);
609 }
610
611 sScriptMgr->OnBattlegroundDesertion(_player, BG_DESERTION_TYPE_INVITE_LOGOUT);
612 }
613
614 _player->RemoveBattlegroundQueueId(bgQueueTypeId);
615 sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId).RemovePlayer(_player->GetGUID(), true);
616 }
617
619 if (Guild* guild = sGuildMgr->GetGuildById(_player->GetGuildId()))
620 guild->HandleMemberLogout(this);
621
623 _player->RemovePet(nullptr, PET_SAVE_AS_CURRENT, true);
624
625 // pussywizard: on logout remove auras that are removed at map change (before saving to db)
626 // there are some positive auras from boss encounters that can be kept by logging out and logging in after boss is dead, and may be used on next bosses
628
630 if (!_player->GetGroup() || sWorld->getBoolConfig(CONFIG_LEAVE_GROUP_ON_LOGOUT))
632
633 // remove player from the group if he is:
634 // a) in group; b) not in raid group; c) logging out normally (not being kicked or disconnected) d) LeaveGroupOnLogout is enabled
637
638 // pussywizard: checked second time after being removed from a group
641
642 // Repop at GraveYard or other player far teleport will prevent saving player because of not present map
643 // Teleport player immediately for correct player save
646
648 // some save parts only correctly work in case player present in map/player_lists (pets, etc)
649 if (save)
650 {
651 uint32 eslot;
652 for (int j = BUYBACK_SLOT_START; j < BUYBACK_SLOT_END; ++j)
653 {
654 eslot = j - BUYBACK_SLOT_START;
658 }
659 _player->SaveToDB(false, true);
660 }
661
664
666 if (_player->GetGroup())
667 {
670
672 {
673 Map::PlayerList const &playerList = _player->GetMap()->GetPlayers();
674 if (playerList.IsEmpty())
676 }
677 }
678
680 sSocialMgr->SendFriendStatus(_player, FRIEND_OFFLINE, _player->GetGUID(), true);
681 sSocialMgr->RemovePlayerSocial(_player->GetGUID());
682
684 sScriptMgr->OnPlayerLogout(_player);
685
686 METRIC_EVENT("player_events", "Logout", _player->GetName());
687
688 LOG_INFO("entities.player", "Account: {} (IP: {}) Logout Character:[{}] ({}) Level: {}",
690
692 // the player may not be in the world when logging out
693 // e.g if he got disconnected during a transfer to another map
694 // calls to GetMap in this case may cause crashes
696 if (Map* _map = _player->FindMap())
697 {
698 _map->RemovePlayerFromMap(_player, true);
699 _map->AfterPlayerUnlinkFromMap();
700 }
701
702 SetPlayer(nullptr); // pointer already deleted
703
707 LOG_DEBUG("network", "SESSION: Sent SMSG_LOGOUT_COMPLETE Message");
708
711 stmt->SetData(0, GetAccountId());
712 CharacterDatabase.Execute(stmt);
713 }
714
715 m_playerLogout = false;
716 m_playerSave = false;
718}
@ CHAR_UPD_ACCOUNT_ONLINE
@ BG_DESERTION_TYPE_INVITE_LOGOUT
Definition: Battleground.h:54
@ PLAYER_FIELD_VENDORBUYBACK_SLOT_1
Definition: UpdateFields.h:331
@ PLAYER_FIELD_BUYBACK_TIMESTAMP_1
Definition: UpdateFields.h:373
@ BUYBACK_SLOT_END
Definition: Player.h:726
@ FRIEND_OFFLINE
Definition: SocialMgr.h:70
#define sOutdoorPvPMgr
@ SPELL_AURA_MOD_SHAPESHIFT
@ SPELL_AURA_SPIRIT_OF_REDEMPTION
@ AURA_INTERRUPT_FLAG_CHANGE_MAP
Definition: SpellDefines.h:63
@ CONFIG_LEAVE_GROUP_ON_LOGOUT
Definition: IWorld.h:176
void SaveToDB(bool create, bool logout)
bool IsBeingTeleportedFar() const
Definition: Player.h:2042
uint32 GetDeathTimer() const
Definition: Player.h:2124
void ResetMaxEnchantingLevel()
Definition: Group.cpp:2155
bool IsRaidOrHeroicDungeon() const
Definition: Map.h:450

◆ LogUnexpectedOpcode()

void WorldSession::LogUnexpectedOpcode ( WorldPacket packet,
char const *  status,
const char *  reason 
)
private

Logging helper for unexpected opcodes.

Definition at line 271 of file WorldSession.cpp.

272{
273 LOG_ERROR("network.opcode", "Received unexpected opcode {} Status: {} Reason: {} from {}",
274 GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), status, reason, GetPlayerInfo());
275}

◆ LogUnprocessedTail()

void WorldSession::LogUnprocessedTail ( WorldPacket packet)
private

Logging helper for unexpected opcodes.

Definition at line 278 of file WorldSession.cpp.

279{
280 if (!sLog->ShouldLog("network.opcode", LogLevel::LOG_LEVEL_TRACE) || packet->rpos() >= packet->wpos())
281 return;
282
283 LOG_TRACE("network.opcode", "Unprocessed tail data (read stop at {} from {}) Opcode {} from {}",
284 uint32(packet->rpos()), uint32(packet->wpos()), GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), GetPlayerInfo());
285
286 packet->print_storage();
287}
#define sLog
Definition: Log.h:128
#define LOG_TRACE(filterType__,...)
Definition: Log.h:175
size_t rpos() const
Definition: ByteBuffer.h:317
void print_storage() const
Definition: ByteBuffer.cpp:153
size_t wpos() const
Definition: ByteBuffer.h:330

◆ moveItems()

void WorldSession::moveItems ( Item myItems[],
Item hisItems[] 
)
private

Definition at line 133 of file TradeHandler.cpp.

134{
135 Player* trader = _player->GetTrader();
136 if (!trader)
137 return;
138
139 for (uint8 i = 0; i < TRADE_SLOT_TRADED_COUNT; ++i)
140 {
141 ItemPosCountVec traderDst;
142 ItemPosCountVec playerDst;
143 bool traderCanTrade = (!myItems[i] || trader->CanStoreItem(NULL_BAG, NULL_SLOT, traderDst, myItems[i], false) == EQUIP_ERR_OK);
144 bool playerCanTrade = (!hisItems[i] || _player->CanStoreItem(NULL_BAG, NULL_SLOT, playerDst, hisItems[i], false) == EQUIP_ERR_OK);
145 if (traderCanTrade && playerCanTrade)
146 {
147 // Ok, if trade item exists and can be stored
148 // If we trade in both directions we had to check, if the trade will work before we actually do it
149 // A roll back is not possible after we stored it
150 if (myItems[i])
151 {
152 // logging
153 LOG_DEBUG("network", "partner storing: {}", myItems[i]->GetGUID().ToString());
154
155 // adjust time (depends on /played)
156 if (myItems[i]->HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_BOP_TRADEABLE))
158 // store
159 trader->MoveItemToInventory(traderDst, myItems[i], true, true);
160 }
161 if (hisItems[i])
162 {
163 // logging
164 LOG_DEBUG("network", "player storing: {}", hisItems[i]->GetGUID().ToString());
165
166 // adjust time (depends on /played)
167 if (hisItems[i]->HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_BOP_TRADEABLE))
169 // store
170 _player->MoveItemToInventory(playerDst, hisItems[i], true, true);
171 }
172 }
173 else
174 {
175 // in case of fatal error log error message
176 // return the already removed items to the original owner
177 if (myItems[i])
178 {
179 if (!traderCanTrade)
180 LOG_ERROR("network.opcode", "trader can't store item: {}", myItems[i]->GetGUID().ToString());
181 if (_player->CanStoreItem(NULL_BAG, NULL_SLOT, playerDst, myItems[i], false) == EQUIP_ERR_OK)
182 _player->MoveItemToInventory(playerDst, myItems[i], true, true);
183 else
184 LOG_ERROR("network.opcode", "player can't take item back: {}", myItems[i]->GetGUID().ToString());
185 }
186 // return the already removed items to the original owner
187 if (hisItems[i])
188 {
189 if (!playerCanTrade)
190 LOG_ERROR("network.opcode", "player can't store item: {}", hisItems[i]->GetGUID().ToString());
191 if (trader->CanStoreItem(NULL_BAG, NULL_SLOT, traderDst, hisItems[i], false) == EQUIP_ERR_OK)
192 trader->MoveItemToInventory(traderDst, hisItems[i], true, true);
193 else
194 LOG_ERROR("network.opcode", "trader can't take item back: {}", hisItems[i]->GetGUID().ToString());
195 }
196 }
197 }
198}
@ ITEM_FIELD_FLAG_BOP_TRADEABLE
Definition: ItemTemplate.h:118
@ ITEM_FIELD_CREATE_PLAYED_TIME
Definition: UpdateFields.h:71
Player * GetTrader() const
Definition: Player.h:1343

◆ operator=()

WorldSession & WorldSession::operator= ( WorldSession const &  right)
privatedelete

◆ PlayerLoading()

bool WorldSession::PlayerLoading ( ) const
inline

Definition at line 335 of file WorldSession.h.

335{ return m_playerLoading; }

◆ PlayerLogout()

bool WorldSession::PlayerLogout ( ) const
inline

Definition at line 336 of file WorldSession.h.

336{ return m_playerLogout; }

◆ PlayerLogoutWithSave()

bool WorldSession::PlayerLogoutWithSave ( ) const
inline

Definition at line 337 of file WorldSession.h.

337{ return m_playerLogout && m_playerSave; }

◆ ProcessQueryCallbacks()

void WorldSession::ProcessQueryCallbacks ( )
private

◆ QueuePacket()

void WorldSession::QueuePacket ( WorldPacket new_packet)

Add an incoming packet to the queue.

Definition at line 265 of file WorldSession.cpp.

266{
267 _recvQueue.add(new_packet);
268}
void add(const T &item)
Adds an item to the queue.
Definition: LockedQueue.h:45

◆ ReadAddonsInfo()

void WorldSession::ReadAddonsInfo ( ByteBuffer data)

Definition at line 1116 of file WorldSession.cpp.

1117{
1118 if (data.rpos() + 4 > data.size())
1119 return;
1120
1121 uint32 size;
1122 data >> size;
1123
1124 if (!size)
1125 return;
1126
1127 if (size > 0xFFFFF)
1128 {
1129 LOG_ERROR("network", "WorldSession::ReadAddonsInfo addon info too big, size {}", size);
1130 return;
1131 }
1132
1133 uLongf uSize = size;
1134
1135 uint32 pos = data.rpos();
1136
1137 ByteBuffer addonInfo;
1138 addonInfo.resize(size);
1139
1140 if (uncompress(addonInfo.contents(), &uSize, data.contents() + pos, data.size() - pos) == Z_OK)
1141 {
1142 uint32 addonsCount;
1143 addonInfo >> addonsCount; // addons count
1144
1145 for (uint32 i = 0; i < addonsCount; ++i)
1146 {
1147 std::string addonName;
1148 uint8 enabled;
1149 uint32 crc, unk1;
1150
1151 // check next addon data format correctness
1152 if (addonInfo.rpos() + 1 > addonInfo.size())
1153 return;
1154
1155 addonInfo >> addonName;
1156
1157 addonInfo >> enabled >> crc >> unk1;
1158
1159 LOG_DEBUG("network", "ADDON: Name: {}, Enabled: 0x{:x}, CRC: 0x{:x}, Unknown2: 0x{:x}", addonName, enabled, crc, unk1);
1160
1161 AddonInfo addon(addonName, enabled, crc, 2, true);
1162
1163 SavedAddon const* savedAddon = AddonMgr::GetAddonInfo(addonName);
1164 if (savedAddon)
1165 {
1166 bool match = true;
1167
1168 if (addon.CRC != savedAddon->CRC)
1169 match = false;
1170
1171 if (!match)
1172 LOG_DEBUG("network", "ADDON: {} was known, but didn't match known CRC (0x{:x})!", addon.Name, savedAddon->CRC);
1173 else
1174 LOG_DEBUG("network", "ADDON: {} was known, CRC is correct (0x{:x})", addon.Name, savedAddon->CRC);
1175 }
1176 else
1177 {
1178 AddonMgr::SaveAddon(addon);
1179
1180 LOG_DEBUG("network", "ADDON: {} (0x{:x}) was not known, saving...", addon.Name, addon.CRC);
1181 }
1182
1183 // TODO: Find out when to not use CRC/pubkey, and other possible states.
1184 m_addonsList.push_back(addon);
1185 }
1186
1187 uint32 currentTime;
1188 addonInfo >> currentTime;
1189 LOG_DEBUG("network", "ADDON: CurrentTime: {}", currentTime);
1190
1191 if (addonInfo.rpos() != addonInfo.size())
1192 LOG_DEBUG("network", "packet under-read!");
1193 }
1194 else
1195 LOG_ERROR("network", "Addon packet uncompress error!");
1196}
SavedAddon const * GetAddonInfo(const std::string &name)
Definition: AddonMgr.cpp:112
void SaveAddon(AddonInfo const &addon)
Definition: AddonMgr.cpp:98
uint32 CRC
Definition: AddonMgr.h:46
AddonsList m_addonsList

◆ ReadMovementInfo()

void WorldSession::ReadMovementInfo ( WorldPacket data,
MovementInfo mi 
)

Anti-cheat checks. Please keep them in seperate if() blocks to maintain a clear overview. Might be subject to latency, so just remove improper flags.

This must be a packet spoofing attempt. MOVEMENTFLAG_ROOT sent from the client is not valid in conjunction with any of the moving movement flags such as MOVEMENTFLAG_FORWARD. It will freeze clients that receive this player's movement info.

Cannot hover without SPELL_AURA_HOVER

Cannot ascend and descend at the same time

Cannot move left and right at the same time

Cannot strafe left and right at the same time

Cannot pitch up and down at the same time

Cannot move forwards and backwards at the same time

Cannot walk on water without SPELL_AURA_WATER_WALK

Cannot feather fall without SPELL_AURA_FEATHER_FALL

Cannot fly if no fly auras present. Exception is being a GM. Note that we check for account level instead of Player::IsGameMaster() because in some situations it may be feasable to use .gm fly on as a GM without having .gm on, e.g. aerial combat.

Cannot fly and fall at the same time

Definition at line 964 of file WorldSession.cpp.

965{
966 data >> mi->flags;
967 data >> mi->flags2;
968 data >> mi->time;
969 data >> mi->pos.PositionXYZOStream();
970
972 {
973 data >> mi->transport.guid.ReadAsPacked();
974
975 data >> mi->transport.pos.PositionXYZOStream();
976 data >> mi->transport.time;
977 data >> mi->transport.seat;
978
980 data >> mi->transport.time2;
981 }
982
984 data >> mi->pitch;
985
986 data >> mi->fallTime;
987
989 {
990 data >> mi->jump.zspeed;
991 data >> mi->jump.sinAngle;
992 data >> mi->jump.cosAngle;
993 data >> mi->jump.xyspeed;
994 }
995
997 data >> mi->splineElevation;
998
1001#ifdef ACORE_DEBUG
1002#define REMOVE_VIOLATING_FLAGS(check, maskToRemove) \
1003 { \
1004 if (check) \
1005 { \
1006 LOG_DEBUG("entities.unit", "WorldSession::ReadMovementInfo: Violation of MovementFlags found ({}). " \
1007 "MovementFlags: {}, MovementFlags2: {} for player {}. Mask {} will be removed.", \
1008 STRINGIZE(check), mi->GetMovementFlags(), mi->GetExtraMovementFlags(), GetPlayer()->GetGUID().ToString(), maskToRemove); \
1009 mi->RemoveMovementFlag((maskToRemove)); \
1010 } \
1011 }
1012#else
1013#define REMOVE_VIOLATING_FLAGS(check, maskToRemove) \
1014 if (check) \
1015 mi->RemoveMovementFlag((maskToRemove));
1016#endif
1017
1024
1028
1032
1036
1040
1044
1048
1051 !GetPlayer()->HasAuraType(SPELL_AURA_WATER_WALK) &&
1052 !GetPlayer()->HasAuraType(SPELL_AURA_GHOST),
1054
1058
1067
1071
1073 (!GetPlayer()->movespline->Initialized() || GetPlayer()->movespline->Finalized()), MOVEMENTFLAG_SPLINE_ENABLED);
1074
1075#undef REMOVE_VIOLATING_FLAGS
1076}
MovementFlags
Definition: Unit.h:550
@ MOVEMENTFLAG_DESCENDING
Definition: Unit.h:575
@ MOVEMENTFLAG_PITCH_DOWN
Definition: Unit.h:559
@ MOVEMENTFLAG_PITCH_UP
Definition: Unit.h:558
@ MOVEMENTFLAG_RIGHT
Definition: Unit.h:557
@ MOVEMENTFLAG_SPLINE_ENABLED
Definition: Unit.h:579
@ MOVEMENTFLAG_FORWARD
Definition: Unit.h:552
@ MOVEMENTFLAG_STRAFE_LEFT
Definition: Unit.h:554
@ MOVEMENTFLAG_BACKWARD
Definition: Unit.h:553
@ MOVEMENTFLAG_WATERWALKING
Definition: Unit.h:580
@ MOVEMENTFLAG_DISABLE_GRAVITY
Definition: Unit.h:562
@ MOVEMENTFLAG_FLYING
Definition: Unit.h:577
@ MOVEMENTFLAG_FALLING_SLOW
Definition: Unit.h:581
@ MOVEMENTFLAG_ROOT
Definition: Unit.h:563
@ MOVEMENTFLAG_LEFT
Definition: Unit.h:556
@ MOVEMENTFLAG_STRAFE_RIGHT
Definition: Unit.h:555
@ MOVEMENTFLAG_ASCENDING
Definition: Unit.h:574
@ MOVEMENTFLAG_HOVER
Definition: Unit.h:582
@ MOVEMENTFLAG_SPLINE_ELEVATION
Definition: Unit.h:578
@ MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING
Definition: Unit.h:613
@ MOVEMENTFLAG2_INTERPOLATED_MOVEMENT
Definition: Unit.h:618
#define REMOVE_VIOLATING_FLAGS(check, maskToRemove)
@ SPELL_AURA_FEATHER_FALL
@ SPELL_AURA_FLY
@ SPELL_AURA_GHOST
@ SPELL_AURA_WATER_WALK
@ SPELL_AURA_HOVER
@ SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED
struct MovementInfo::JumpInfo jump
uint16 flags2
Definition: Object.h:268
float splineElevation
Definition: Object.h:309
float pitch
Definition: Object.h:292
bool HasExtraMovementFlag(uint16 flag) const
Definition: Object.h:326
Position::PositionXYZOStreamer PositionXYZOStream()
Definition: Position.h:150

◆ recoveryItem()

bool WorldSession::recoveryItem ( Item pItem)
private

Definition at line 1638 of file ItemHandler.cpp.

1639{
1640 if (sWorld->getBoolConfig(CONFIG_ITEMDELETE_METHOD)
1641 && pItem->GetTemplate()->Quality >= sWorld->getIntConfig(CONFIG_ITEMDELETE_QUALITY)
1642 && pItem->GetTemplate()->ItemLevel >= sWorld->getIntConfig(CONFIG_ITEMDELETE_ITEM_LEVEL))
1643 {
1645
1646 stmt->SetData(0, pItem->GetOwnerGUID().GetCounter());
1647 stmt->SetData(1, pItem->GetTemplate()->ItemId);
1648 stmt->SetData(2, pItem->GetCount());
1649
1650 CharacterDatabase.Query(stmt);
1651
1652 return true;
1653 }
1654
1655 return false;
1656}
@ CHAR_INS_RECOVERY_ITEM
@ CONFIG_ITEMDELETE_QUALITY
Definition: IWorld.h:377
@ CONFIG_ITEMDELETE_ITEM_LEVEL
Definition: IWorld.h:378
@ CONFIG_ITEMDELETE_METHOD
Definition: IWorld.h:162

◆ ResetTimeOutTime()

void WorldSession::ResetTimeOutTime ( bool  onlyActive)
inline

Definition at line 510 of file WorldSession.h.

511 {
512 if (GetPlayer())
514 else if (!onlyActive)
516 }
@ CONFIG_SOCKET_TIMEOUTTIME
Definition: IWorld.h:209
@ CONFIG_SOCKET_TIMEOUTTIME_ACTIVE
Definition: IWorld.h:372

◆ ResetTimeSync()

void WorldSession::ResetTimeSync ( )

Definition at line 1612 of file WorldSession.cpp.

1613{
1616}

◆ SaveTutorialsData()

void WorldSession::SaveTutorialsData ( CharacterDatabaseTransaction  trans)

Definition at line 945 of file WorldSession.cpp.

946{
948 return;
949
951 stmt->SetData(0, GetAccountId());
952 bool hasTutorials = bool(CharacterDatabase.Query(stmt));
953
954 stmt = CharacterDatabase.GetPreparedStatement(hasTutorials ? CHAR_UPD_TUTORIALS : CHAR_INS_TUTORIALS);
955
956 for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
957 stmt->SetData(i, m_Tutorials[i]);
959 trans->Append(stmt);
960
961 m_TutorialsChanged = false;
962}
@ CHAR_INS_TUTORIALS
@ CHAR_UPD_TUTORIALS
@ CHAR_SEL_HAS_TUTORIALS

◆ SendAccountDataTimes()

void WorldSession::SendAccountDataTimes ( uint32  mask)

Definition at line 912 of file WorldSession.cpp.

913{
914 WorldPacket data(SMSG_ACCOUNT_DATA_TIMES, 4 + 1 + 4 + 8 * 4); // changed in WotLK
915 data << uint32(GameTime::GetGameTime().count()); // unix time of something
916 data << uint8(1);
917 data << uint32(mask); // type mask
918 for (uint32 i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i)
919 if (mask & (1 << i))
920 data << uint32(GetAccountData(AccountDataType(i))->Time);// also unix time
921 SendPacket(&data);
922}
@ SMSG_ACCOUNT_DATA_TIMES
Definition: Opcodes.h:551

◆ SendActivateTaxiReply()

void WorldSession::SendActivateTaxiReply ( ActivateTaxiReply  reply)

Definition at line 294 of file TaxiHandler.cpp.

295{
296 GetPlayer()->SetCanTeleport(true);
298 data << uint32(reply);
299 SendPacket(&data);
300
301 LOG_DEBUG("network", "WORLD: Sent SMSG_ACTIVATETAXIREPLY");
302}
@ SMSG_ACTIVATETAXIREPLY
Definition: Opcodes.h:460

◆ SendAddonsInfo()

void WorldSession::SendAddonsInfo ( )

Definition at line 1198 of file WorldSession.cpp.

1199{
1200 uint8 addonPublicKey[256] =
1201 {
1202 0xC3, 0x5B, 0x50, 0x84, 0xB9, 0x3E, 0x32, 0x42, 0x8C, 0xD0, 0xC7, 0x48, 0xFA, 0x0E, 0x5D, 0x54,
1203 0x5A, 0xA3, 0x0E, 0x14, 0xBA, 0x9E, 0x0D, 0xB9, 0x5D, 0x8B, 0xEE, 0xB6, 0x84, 0x93, 0x45, 0x75,
1204 0xFF, 0x31, 0xFE, 0x2F, 0x64, 0x3F, 0x3D, 0x6D, 0x07, 0xD9, 0x44, 0x9B, 0x40, 0x85, 0x59, 0x34,
1205 0x4E, 0x10, 0xE1, 0xE7, 0x43, 0x69, 0xEF, 0x7C, 0x16, 0xFC, 0xB4, 0xED, 0x1B, 0x95, 0x28, 0xA8,
1206 0x23, 0x76, 0x51, 0x31, 0x57, 0x30, 0x2B, 0x79, 0x08, 0x50, 0x10, 0x1C, 0x4A, 0x1A, 0x2C, 0xC8,
1207 0x8B, 0x8F, 0x05, 0x2D, 0x22, 0x3D, 0xDB, 0x5A, 0x24, 0x7A, 0x0F, 0x13, 0x50, 0x37, 0x8F, 0x5A,
1208 0xCC, 0x9E, 0x04, 0x44, 0x0E, 0x87, 0x01, 0xD4, 0xA3, 0x15, 0x94, 0x16, 0x34, 0xC6, 0xC2, 0xC3,
1209 0xFB, 0x49, 0xFE, 0xE1, 0xF9, 0xDA, 0x8C, 0x50, 0x3C, 0xBE, 0x2C, 0xBB, 0x57, 0xED, 0x46, 0xB9,
1210 0xAD, 0x8B, 0xC6, 0xDF, 0x0E, 0xD6, 0x0F, 0xBE, 0x80, 0xB3, 0x8B, 0x1E, 0x77, 0xCF, 0xAD, 0x22,
1211 0xCF, 0xB7, 0x4B, 0xCF, 0xFB, 0xF0, 0x6B, 0x11, 0x45, 0x2D, 0x7A, 0x81, 0x18, 0xF2, 0x92, 0x7E,
1212 0x98, 0x56, 0x5D, 0x5E, 0x69, 0x72, 0x0A, 0x0D, 0x03, 0x0A, 0x85, 0xA2, 0x85, 0x9C, 0xCB, 0xFB,
1213 0x56, 0x6E, 0x8F, 0x44, 0xBB, 0x8F, 0x02, 0x22, 0x68, 0x63, 0x97, 0xBC, 0x85, 0xBA, 0xA8, 0xF7,
1214 0xB5, 0x40, 0x68, 0x3C, 0x77, 0x86, 0x6F, 0x4B, 0xD7, 0x88, 0xCA, 0x8A, 0xD7, 0xCE, 0x36, 0xF0,
1215 0x45, 0x6E, 0xD5, 0x64, 0x79, 0x0F, 0x17, 0xFC, 0x64, 0xDD, 0x10, 0x6F, 0xF3, 0xF5, 0xE0, 0xA6,
1216 0xC3, 0xFB, 0x1B, 0x8C, 0x29, 0xEF, 0x8E, 0xE5, 0x34, 0xCB, 0xD1, 0x2A, 0xCE, 0x79, 0xC3, 0x9A,
1217 0x0D, 0x36, 0xEA, 0x01, 0xE0, 0xAA, 0x91, 0x20, 0x54, 0xF0, 0x72, 0xD8, 0x1E, 0xC7, 0x89, 0xD2
1218 };
1219
1221
1222 for (AddonsList::iterator itr = m_addonsList.begin(); itr != m_addonsList.end(); ++itr)
1223 {
1224 data << uint8(itr->State);
1225
1226 uint8 crcpub = itr->UsePublicKeyOrCRC;
1227 data << uint8(crcpub);
1228 if (crcpub)
1229 {
1230 uint8 usepk = (itr->CRC != STANDARD_ADDON_CRC); // If addon is Standard addon CRC
1231 data << uint8(usepk);
1232 if (usepk) // if CRC is wrong, add public key (client need it)
1233 {
1234 LOG_DEBUG("network", "ADDON: CRC (0x{:x}) for addon {} is wrong (does not match expected 0x{:x}), sending pubkey", itr->CRC, itr->Name, STANDARD_ADDON_CRC);
1235 data.append(addonPublicKey, sizeof(addonPublicKey));
1236 }
1237
1238 data << uint32(0); // TODO: Find out the meaning of this.
1239 }
1240
1241 uint8 unk3 = 0; // 0 is sent here
1242 data << uint8(unk3);
1243 if (unk3)
1244 {
1245 // String, length 256 (null terminated)
1246 data << uint8(0);
1247 }
1248 }
1249
1250 m_addonsList.clear();
1251
1253 data << uint32(bannedAddons->size());
1254 for (AddonMgr::BannedAddonList::const_iterator itr = bannedAddons->begin(); itr != bannedAddons->end(); ++itr)
1255 {
1256 data << uint32(itr->Id);
1257 data.append(itr->NameMD5, sizeof(itr->NameMD5));
1258 data.append(itr->VersionMD5, sizeof(itr->VersionMD5));
1259 data << uint32(itr->Timestamp);
1260 data << uint32(1); // IsBanned
1261 }
1262
1263 SendPacket(&data);
1264}
#define STANDARD_ADDON_CRC
Definition: AddonMgr.h:57
@ SMSG_ADDON_INFO
Definition: Opcodes.h:781
std::list< BannedAddon > BannedAddonList
Definition: AddonMgr.h:65
BannedAddonList const * GetBannedAddons()
Definition: AddonMgr.cpp:125

◆ SendAreaTriggerMessage()

void WorldSession::SendAreaTriggerMessage ( const char *  Text,
  ... 
)

Definition at line 710 of file MiscHandler.cpp.

711{
712 va_list ap;
713 char szStr [1024];
714 szStr[0] = '\0';
715
716 va_start(ap, Text);
717 vsnprintf(szStr, 1024, Text, ap);
718 va_end(ap);
719
720 uint32 length = strlen(szStr) + 1;
721 WorldPacket data(SMSG_AREA_TRIGGER_MESSAGE, 4 + length);
722 data << length;
723 data << szStr;
724 SendPacket(&data);
725}
@ SMSG_AREA_TRIGGER_MESSAGE
Definition: Opcodes.h:726

◆ SendArenaTeamCommandResult()

void WorldSession::SendArenaTeamCommandResult ( uint32  team_action,
std::string const &  team,
std::string const &  player,
uint32  error_id = 0 
)

Definition at line 397 of file ArenaTeamHandler.cpp.

398{
399 WorldPacket data(SMSG_ARENA_TEAM_COMMAND_RESULT, 4 + team.length() + 1 + player.length() + 1 + 4);
400 data << uint32(teamAction);
401 data << team;
402 data << player;
403 data << uint32(errorId);
404 SendPacket(&data);
405}
@ SMSG_ARENA_TEAM_COMMAND_RESULT
Definition: Opcodes.h:871

◆ SendAttackStop()

void WorldSession::SendAttackStop ( Unit const *  enemy)

Definition at line 85 of file CombatHandler.cpp.

86{
87 WorldPacket data(SMSG_ATTACKSTOP, (8 + 8 + 4)); // we guess size
88 data << GetPlayer()->GetPackGUID();
89 data << (enemy ? enemy->GetPackGUID() : PackedGuid()); // must be packed guid
90 data << uint32(0); // unk, can be 1 also
91 SendPacket(&data);
92}
@ SMSG_ATTACKSTOP
Definition: Opcodes.h:354

◆ SendAuctionBidderNotification()

void WorldSession::SendAuctionBidderNotification ( uint32  location,
uint32  auctionId,
ObjectGuid  bidder,
uint32  bidSum,
uint32  diff,
uint32  item_template 
)

Definition at line 89 of file AuctionHouseHandler.cpp.

90{
92 data << uint32(location);
93 data << uint32(auctionId);
94 data << bidder;
95 data << uint32(bidSum);
96 data << uint32(diff);
97 data << uint32(item_template);
98 data << uint32(0);
99 SendPacket(&data);
100}
@ SMSG_AUCTION_BIDDER_NOTIFICATION
Definition: Opcodes.h:636

◆ SendAuctionCommandResult()

void WorldSession::SendAuctionCommandResult ( uint32  auctionId,
uint32  Action,
uint32  ErrorCode,
uint32  bidError = 0 
)

Definition at line 77 of file AuctionHouseHandler.cpp.

78{
80 data << auctionId;
81 data << Action;
82 data << ErrorCode;
83 if (!ErrorCode && Action)
84 data << bidError; //when bid, then send 0, once...
85 SendPacket(&data);
86}
Action
@ SMSG_AUCTION_COMMAND_RESULT
Definition: Opcodes.h:633

◆ SendAuctionHello()

void WorldSession::SendAuctionHello ( ObjectGuid  guid,
Creature unit 
)

Definition at line 54 of file AuctionHouseHandler.cpp.

55{
56 if (GetPlayer()->getLevel() < sWorld->getIntConfig(CONFIG_AUCTION_LEVEL_REQ))
57 {
59 return;
60 }
61
62 if (!sScriptMgr->CanSendAuctionHello(this, guid, unit))
63 return;
64
66 if (!ahEntry)
67 return;
68
70 data << guid;
71 data << uint32(ahEntry->houseId);
72 data << uint8(1); // 3.3.3: 1 - AH enabled, 0 - AH disabled
73 SendPacket(&data);
74}
@ LANG_AUCTION_REQ
Definition: Language.h:1157
@ CONFIG_AUCTION_LEVEL_REQ
Definition: IWorld.h:291
@ MSG_AUCTION_HELLO
Definition: Opcodes.h:627

◆ SendAuctionOwnerNotification()

void WorldSession::SendAuctionOwnerNotification ( AuctionEntry auction)

Definition at line 103 of file AuctionHouseHandler.cpp.

104{
106 data << uint32(auction->Id);
107 data << uint32(auction->bid);
108 data << uint32(0); //unk
109 data << uint64(0); //unk (bidder guid?)
110 data << uint32(auction->item_template);
111 data << uint32(0); //unk
112 data << float(0); //unk (time?)
113 SendPacket(&data);
114}
@ SMSG_AUCTION_OWNER_NOTIFICATION
Definition: Opcodes.h:637

◆ SendAuthResponse()

void WorldSession::SendAuthResponse ( uint8  code,
bool  shortForm,
uint32  queuePos = 0 
)

Definition at line 22 of file AuthHandler.cpp.

23{
24 WorldPacket packet(SMSG_AUTH_RESPONSE, 1 + 4 + 1 + 4 + 1 + (shortForm ? 0 : (4 + 1)));
25 packet << uint8(code);
26 packet << uint32(0); // BillingTimeRemaining
27 packet << uint8(0); // BillingPlanFlags
28 packet << uint32(0); // BillingTimeRested
29 packet << uint8(Expansion()); // 0 - normal, 1 - TBC, 2 - WOTLK, must be set in database manually for each account
30
31 if (!shortForm)
32 {
33 packet << uint32(queuePos); // Queue position
34 packet << uint8(0); // Realm has a free character migration - bool
35 }
36
37 SendPacket(&packet);
38}
@ SMSG_AUTH_RESPONSE
Definition: Opcodes.h:524

◆ SendAuthWaitQueue()

void WorldSession::SendAuthWaitQueue ( uint32  position)

Handle the authentication waiting queue (to be completed)

Definition at line 827 of file WorldSession.cpp.

828{
829 if (position == 0)
830 {
832 packet << uint8(AUTH_OK);
833 SendPacket(&packet);
834 }
835 else
836 {
838 packet << uint8(AUTH_WAIT_QUEUE);
839 packet << uint32(position);
840 packet << uint8(0); // unk
841 SendPacket(&packet);
842 }
843}
@ AUTH_WAIT_QUEUE
@ AUTH_OK

◆ SendBattleGroundList()

void WorldSession::SendBattleGroundList ( ObjectGuid  guid,
BattlegroundTypeId  bgTypeId = BATTLEGROUND_RB 
)

Definition at line 64 of file BattleGroundHandler.cpp.

65{
66 WorldPacket data;
67 sBattlegroundMgr->BuildBattlegroundListPacket(&data, guid, _player, bgTypeId, 0);
68 SendPacket(&data);
69}

◆ SendBfEntered()

void WorldSession::SendBfEntered ( uint32  battleId)

Definition at line 74 of file BattlefieldHandler.cpp.

75{
76 // m_PlayerInWar[player->GetTeamId()].insert(player->GetGUID());
78 data << uint32(BattleId);
79 data << uint8(1); //unk
80 data << uint8(1); //unk
81 data << uint8(_player->isAFK() ? 1 : 0); //Clear AFK
82 SendPacket(&data);
83}
@ SMSG_BATTLEFIELD_MGR_ENTERED
Definition: Opcodes.h:1278

◆ SendBfInvitePlayerToQueue()

void WorldSession::SendBfInvitePlayerToQueue ( uint32  battleId)

Definition at line 45 of file BattlefieldHandler.cpp.

46{
48
49 data << uint32(BattleId);
50 data << uint8(1); //warmup ? used ?
51
52 //Sending packet to player
53 SendPacket(&data);
54}
@ SMSG_BATTLEFIELD_MGR_QUEUE_INVITE
Definition: Opcodes.h:1279

◆ SendBfInvitePlayerToWar()

void WorldSession::SendBfInvitePlayerToWar ( uint32  battleId,
uint32  zoneId,
uint32  time 
)

Definition at line 31 of file BattlefieldHandler.cpp.

32{
33 //Send packet
35 data << uint32(BattleId);
36 data << uint32(ZoneId);
37 data << uint32((GameTime::GetGameTime().count() + p_time));
38
39 //Sending the packet to player
40 SendPacket(&data);
41}
@ SMSG_BATTLEFIELD_MGR_ENTRY_INVITE
Definition: Opcodes.h:1276

◆ SendBfLeaveMessage()

void WorldSession::SendBfLeaveMessage ( uint32  battleId,
BFLeaveReason  reason = BF_LEAVE_REASON_EXITED 
)

Definition at line 85 of file BattlefieldHandler.cpp.

86{
88 data << uint32(BattleId);
89 data << uint8(reason);//byte Reason
90 data << uint8(2);//byte BattleStatus
91 data << uint8(0);//bool Relocated
92 SendPacket(&data);
93}
@ SMSG_BATTLEFIELD_MGR_EJECTED
Definition: Opcodes.h:1284

◆ SendBfQueueInviteResponse()

void WorldSession::SendBfQueueInviteResponse ( uint32  battleId,
uint32  zoneId,
bool  canQueue = true,
bool  full = false 
)

Definition at line 61 of file BattlefieldHandler.cpp.

62{
64 data << uint32(BattleId);
65 data << uint32(ZoneId);
66 data << uint8((CanQueue ? 1 : 0)); //Accepted //0 you cannot queue wg //1 you are queued
67 data << uint8((Full ? 0 : 1)); //Logging In //0 wg full //1 queue for upcoming
68 data << uint8(1); //Warmup
69 SendPacket(&data);
70}
@ SMSG_BATTLEFIELD_MGR_QUEUE_REQUEST_RESPONSE
Definition: Opcodes.h:1282

◆ SendBindPoint()

void WorldSession::SendBindPoint ( Creature npc)

Definition at line 447 of file NPCHandler.cpp.

448{
449 // prevent set homebind to instances in any case
450 if (GetPlayer()->GetMap()->Instanceable())
451 return;
452
453 uint32 bindspell = 3286;
454
455 // send spell for homebinding (3286)
456 npc->CastSpell(_player, bindspell, true);
457
459 data << npc->GetGUID();
460 data << uint32(bindspell);
461 SendPacket(&data);
462
464}

◆ SendCalendarRaidLockout()

void WorldSession::SendCalendarRaidLockout ( InstanceSave const *  save,
bool  add 
)

Definition at line 818 of file CalendarHandler.cpp.

819{
820 LOG_DEBUG("network", "{}", add ? "SMSG_CALENDAR_RAID_LOCKOUT_ADDED" : "SMSG_CALENDAR_RAID_LOCKOUT_REMOVED");
821 time_t currTime = GameTime::GetGameTime().count();
822
823 WorldPacket data(SMSG_CALENDAR_RAID_LOCKOUT_REMOVED, (add ? 4 : 0) + 4 + 4 + 4 + 8);
824 if (add)
825 {
826 data.SetOpcode(SMSG_CALENDAR_RAID_LOCKOUT_ADDED);
827 data.AppendPackedTime(currTime);
828 }
829
830 data << uint32(save->GetMapId());
831 data << uint32(save->GetDifficulty());
832 data << uint32(save->GetResetTime() >= currTime ? save->GetResetTime() - currTime : 0);
833 data << ObjectGuid::Create<HighGuid::Instance>(save->GetInstanceId());
834 SendPacket(&data);
835}
@ SMSG_CALENDAR_RAID_LOCKOUT_ADDED
Definition: Opcodes.h:1116
@ SMSG_CALENDAR_RAID_LOCKOUT_REMOVED
Definition: Opcodes.h:1117

◆ SendCalendarRaidLockoutUpdated()

void WorldSession::SendCalendarRaidLockoutUpdated ( InstanceSave const *  save,
bool  isExtended 
)

Definition at line 837 of file CalendarHandler.cpp.

838{
839 time_t currTime = GameTime::GetGameTime().count();
840 time_t resetTime = isExtended ? save->GetExtendedResetTime() : save->GetResetTime();
841 time_t resetTimeOp = isExtended ? save->GetResetTime() : save->GetExtendedResetTime();
842 WorldPacket data(SMSG_CALENDAR_RAID_LOCKOUT_UPDATED, 4 + 4 + 4 + 4 + 8);
843 data.AppendPackedTime(currTime);
844 data << uint32(save->GetMapId());
845 data << uint32(save->GetDifficulty());
846 data << uint32(resetTimeOp >= currTime ? resetTimeOp - currTime : resetTimeOp); // pussywizard: old time in secs to reset
847 data << uint32(resetTime >= currTime ? resetTime - currTime : 0); // pussywizard: new time in secs to reset
848 SendPacket(&data);
849}
@ SMSG_CALENDAR_RAID_LOCKOUT_UPDATED
Definition: Opcodes.h:1167

◆ SendCancelTrade()

void WorldSession::SendCancelTrade ( )

Definition at line 528 of file TradeHandler.cpp.

529{
530 if (PlayerLogout())
531 return;
532
534}

◆ SendCharCreate()

void WorldSession::SendCharCreate ( ResponseCodes  result)

Definition at line 2567 of file CharacterHandler.cpp.

2568{
2570 data << uint8(result);
2571 SendPacket(&data);
2572}
@ SMSG_CHAR_CREATE
Definition: Opcodes.h:88

◆ SendCharCustomize()

void WorldSession::SendCharCustomize ( ResponseCodes  result,
CharacterCustomizeInfo const *  customizeInfo 
)

Definition at line 2612 of file CharacterHandler.cpp.

2613{
2614 WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1 + 8 + customizeInfo->Name.size() + 1 + 6);
2615 data << uint8(result);
2616 if (result == RESPONSE_SUCCESS)
2617 {
2618 data << customizeInfo->Guid;
2619 data << customizeInfo->Name;
2620 data << uint8(customizeInfo->Gender);
2621 data << uint8(customizeInfo->Skin);
2622 data << uint8(customizeInfo->Face);
2623 data << uint8(customizeInfo->HairStyle);
2624 data << uint8(customizeInfo->HairColor);
2625 data << uint8(customizeInfo->FacialHair);
2626 }
2627 SendPacket(&data);
2628}

◆ SendCharDelete()

void WorldSession::SendCharDelete ( ResponseCodes  result)

Definition at line 2574 of file CharacterHandler.cpp.

2575{
2577 data << uint8(result);
2578 SendPacket(&data);
2579}
@ SMSG_CHAR_DELETE
Definition: Opcodes.h:90

◆ SendCharFactionChange()

void WorldSession::SendCharFactionChange ( ResponseCodes  result,
CharacterFactionChangeInfo const *  factionChangeInfo 
)

Definition at line 2593 of file CharacterHandler.cpp.

2594{
2595 WorldPacket data(SMSG_CHAR_FACTION_CHANGE, 1 + 8 + factionChangeInfo->Name.size() + 1 + 7);
2596 data << uint8(result);
2597 if (result == RESPONSE_SUCCESS)
2598 {
2599 data << factionChangeInfo->Guid;
2600 data << factionChangeInfo->Name;
2601 data << uint8(factionChangeInfo->Gender);
2602 data << uint8(factionChangeInfo->Skin);
2603 data << uint8(factionChangeInfo->Face);
2604 data << uint8(factionChangeInfo->HairStyle);
2605 data << uint8(factionChangeInfo->HairColor);
2606 data << uint8(factionChangeInfo->FacialHair);
2607 data << uint8(factionChangeInfo->Race);
2608 }
2609 SendPacket(&data);
2610}
@ SMSG_CHAR_FACTION_CHANGE
Definition: Opcodes.h:1272

◆ SendCharRename()

void WorldSession::SendCharRename ( ResponseCodes  result,
CharacterRenameInfo const *  renameInfo 
)

Definition at line 2581 of file CharacterHandler.cpp.

2582{
2583 WorldPacket data(SMSG_CHAR_RENAME, 1 + 8 + renameInfo->Name.size() + 1);
2584 data << uint8(result);
2585 if (result == RESPONSE_SUCCESS)
2586 {
2587 data << renameInfo->Guid;
2588 data << renameInfo->Name;
2589 }
2590 SendPacket(&data);
2591}
@ SMSG_CHAR_RENAME
Definition: Opcodes.h:742

◆ SendChatRestrictedNotice()

void WorldSession::SendChatRestrictedNotice ( ChatRestrictionType  restriction)

Definition at line 831 of file ChatHandler.cpp.

832{
834 data << uint8(restriction);
835 SendPacket(&data);
836}
@ SMSG_CHAT_RESTRICTED
Definition: Opcodes.h:795

◆ SendClientCacheVersion()

void WorldSession::SendClientCacheVersion ( uint32  version)

Definition at line 40 of file AuthHandler.cpp.

41{
43 data << uint32(version);
44 SendPacket(&data);
45}
@ SMSG_CLIENTCACHE_VERSION
Definition: Opcodes.h:1225

◆ SendDiscoverNewTaxiNode()

void WorldSession::SendDiscoverNewTaxiNode ( uint32  nodeid)

Definition at line 160 of file TaxiHandler.cpp.

161{
162 if (GetPlayer()->m_taxi.SetTaximaskNode(nodeid))
163 {
165 SendPacket(&msg);
166 }
167}
@ SMSG_NEW_TAXI_PATH
Definition: Opcodes.h:461

◆ SendDoFlight()

void WorldSession::SendDoFlight ( uint32  mountDisplayId,
uint32  path,
uint32  pathNode = 0 
)

Definition at line 114 of file TaxiHandler.cpp.

115{
116 // remove fake death
117 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
119
120 while (GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE)
122
123 if (mountDisplayId)
124 GetPlayer()->Mount(mountDisplayId);
125
126 if (Creature* critter = ObjectAccessor::GetCreature(*GetPlayer(), GetPlayer()->GetCritterGUID()))
127 {
128 critter->DespawnOrUnsummon();
129 }
130
131 GetPlayer()->GetMotionMaster()->MoveTaxiFlight(path, pathNode);
132
133 sScriptMgr->AnticheatSetSkipOnePacketForASH(GetPlayer(), true);
134}
Creature * GetCreature(WorldObject const &u, ObjectGuid const guid)
void Mount(uint32 mount, uint32 vehicleId=0, uint32 creatureEntry=0)
Definition: Unit.cpp:13369
void MoveTaxiFlight(uint32 path, uint32 pathnode)

◆ SendEnchantmentLog()

void WorldSession::SendEnchantmentLog ( ObjectGuid  target,
ObjectGuid  caster,
uint32  itemId,
uint32  enchantId 
)

Definition at line 1179 of file ItemHandler.cpp.

1180{
1181 WorldPacket data(SMSG_ENCHANTMENTLOG, (8 + 8 + 4 + 4)); // last check 2.0.10
1182 data << target.WriteAsPacked();
1183 data << caster.WriteAsPacked();
1184 data << uint32(itemId);
1185 data << uint32(enchantId);
1186 GetPlayer()->SendMessageToSet(&data, true);
1187}
@ SMSG_ENCHANTMENTLOG
Definition: Opcodes.h:501

◆ SendItemEnchantTimeUpdate()

void WorldSession::SendItemEnchantTimeUpdate ( ObjectGuid  Playerguid,
ObjectGuid  Itemguid,
uint32  slot,
uint32  Duration 
)

Definition at line 1189 of file ItemHandler.cpp.

1190{
1191 // last check 2.0.10
1192 WorldPacket data(SMSG_ITEM_ENCHANT_TIME_UPDATE, (8 + 4 + 4 + 8));
1193 data << Itemguid;
1194 data << uint32(slot);
1195 data << uint32(Duration);
1196 data << Playerguid;
1197 SendPacket(&data);
1198}
@ SMSG_ITEM_ENCHANT_TIME_UPDATE
Definition: Opcodes.h:521

◆ SendLearnNewTaxiNode()

bool WorldSession::SendLearnNewTaxiNode ( Creature unit)

Definition at line 136 of file TaxiHandler.cpp.

137{
138 // find current node
139 uint32 curloc = sObjectMgr->GetNearestTaxiNode(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), unit->GetMapId(), GetPlayer()->GetTeamId());
140
141 if (curloc == 0)
142 return true; // `true` send to avoid WorldSession::SendTaxiMenu call with one more curlock seartch with same false result.
143
144 if (GetPlayer()->m_taxi.SetTaximaskNode(curloc))
145 {
147 SendPacket(&msg);
148
150 update << unit->GetGUID();
151 update << uint8(1);
152 SendPacket(&update);
153
154 return true;
155 }
156 else
157 return false;
158}
@ SMSG_TAXINODE_STATUS
Definition: Opcodes.h:457

◆ SendLfgBootProposalUpdate()

void WorldSession::SendLfgBootProposalUpdate ( lfg::LfgPlayerBoot const &  boot)

Definition at line 502 of file LFGHandler.cpp.

503{
504 ObjectGuid guid = GetPlayer()->GetGUID();
505 lfg::LfgAnswer playerVote = boot.votes.find(guid)->second;
506 uint8 votesNum = 0;
507 uint8 agreeNum = 0;
508 uint32 secsleft = boot.cancelTime - GameTime::GetGameTime().count();
509 for (lfg::LfgAnswerContainer::const_iterator it = boot.votes.begin(); it != boot.votes.end(); ++it)
510 {
511 if (it->second != lfg::LFG_ANSWER_PENDING)
512 {
513 ++votesNum;
514 if (it->second == lfg::LFG_ANSWER_AGREE)
515 ++agreeNum;
516 }
517 }
518 LOG_DEBUG("network", "SMSG_LFG_BOOT_PROPOSAL_UPDATE [{}] inProgress: {} - didVote: {} - agree: {} - victim: [{}] votes: {} - agrees: {} - left: {} - needed: {} - reason {}",
519 guid.ToString(), uint8(boot.inProgress), uint8(playerVote != lfg::LFG_ANSWER_PENDING), uint8(playerVote == lfg::LFG_ANSWER_AGREE),
520 boot.victim.ToString(), votesNum, agreeNum, secsleft, lfg::LFG_GROUP_KICK_VOTES_NEEDED, boot.reason);
521 WorldPacket data(SMSG_LFG_BOOT_PROPOSAL_UPDATE, 1 + 1 + 1 + 8 + 4 + 4 + 4 + 4 + boot.reason.length());
522 data << uint8(boot.inProgress); // Vote in progress
523 data << uint8(playerVote != lfg::LFG_ANSWER_PENDING); // Did Vote
524 data << uint8(playerVote == lfg::LFG_ANSWER_AGREE); // Agree
525 data << boot.victim; // Victim GUID
526 data << uint32(votesNum); // Total Votes
527 data << uint32(agreeNum); // Agree Count
528 data << uint32(secsleft); // Time Left
529 data << uint32(lfg::LFG_GROUP_KICK_VOTES_NEEDED); // Needed Votes
530 data << boot.reason.c_str(); // Kick reason
531 SendPacket(&data);
532}
@ SMSG_LFG_BOOT_PROPOSAL_UPDATE
Definition: Opcodes.h:907
@ LFG_GROUP_KICK_VOTES_NEEDED
Definition: LFGMgr.h:55
LfgAnswer
Answer state (Also used to check compatibilites)
Definition: LFG.h:100
@ LFG_ANSWER_AGREE
Definition: LFG.h:103
@ LFG_ANSWER_PENDING
Definition: LFG.h:101

◆ SendLfgDisabled()

void WorldSession::SendLfgDisabled ( )

Definition at line 590 of file LFGHandler.cpp.

591{
592 LOG_DEBUG("network", "SMSG_LFG_DISABLED [{}]", GetPlayer()->GetGUID().ToString());
594 SendPacket(&data);
595}
@ SMSG_LFG_DISABLED
Definition: Opcodes.h:950

◆ SendLfgJoinResult()

void WorldSession::SendLfgJoinResult ( lfg::LfgJoinResultData const &  joinData)

Definition at line 432 of file LFGHandler.cpp.

433{
434 uint32 size = 0;
435 for (lfg::LfgLockPartyMap::const_iterator it = joinData.lockmap.begin(); it != joinData.lockmap.end(); ++it)
436 size += 8 + 4 + uint32(it->second.size()) * (4 + 4);
437
438 LOG_DEBUG("network", "SMSG_LFG_JOIN_RESULT [{}] checkResult: {} checkValue: {}", GetPlayer()->GetGUID().ToString(), joinData.result, joinData.state);
439 WorldPacket data(SMSG_LFG_JOIN_RESULT, 4 + 4 + size);
440 data << uint32(joinData.result); // Check Result
441 data << uint32(joinData.state); // Check Value
442 if (!joinData.lockmap.empty())
443 BuildPartyLockDungeonBlock(data, joinData.lockmap);
444 SendPacket(&data);
445}
@ SMSG_LFG_JOIN_RESULT
Definition: Opcodes.h:898

◆ SendLfgLfrList()

void WorldSession::SendLfgLfrList ( bool  update)

Definition at line 582 of file LFGHandler.cpp.

583{
584 LOG_DEBUG("network", "SMSG_LFG_LFR_LIST [{}] update: {}", GetPlayer()->GetGUID().ToString(), update ? 1 : 0);
586 data << uint8(update); // In Lfg Queue?
587 SendPacket(&data);
588}
@ SMSG_LFG_UPDATE_SEARCH
Definition: Opcodes.h:903

◆ SendLfgOfferContinue()

void WorldSession::SendLfgOfferContinue ( uint32  dungeonEntry)

Definition at line 597 of file LFGHandler.cpp.

598{
599 LOG_DEBUG("network", "SMSG_LFG_OFFER_CONTINUE [{}] dungeon entry: {}", GetPlayer()->GetGUID().ToString(), dungeonEntry);
601 data << uint32(dungeonEntry);
602 SendPacket(&data);
603}
@ SMSG_LFG_OFFER_CONTINUE
Definition: Opcodes.h:689

◆ SendLfgPlayerReward()

void WorldSession::SendLfgPlayerReward ( lfg::LfgPlayerRewardData const &  lfgPlayerRewardData)

Definition at line 466 of file LFGHandler.cpp.

467{
468 if (!rewardData.rdungeonEntry || !rewardData.sdungeonEntry || !rewardData.quest)
469 return;
470
471 LOG_DEBUG("lfg", "SMSG_LFG_PLAYER_REWARD {} rdungeonEntry: {}, sdungeonEntry: {}, done: {}",
472 GetPlayerInfo(), rewardData.rdungeonEntry, rewardData.sdungeonEntry, rewardData.done);
473
474 uint8 itemNum = rewardData.quest->GetRewItemsCount();
475
476 uint8 playerLevel = GetPlayer() ? GetPlayer()->getLevel() : 0;
477
478 WorldPacket data(SMSG_LFG_PLAYER_REWARD, 4 + 4 + 1 + 4 + 4 + 4 + 4 + 4 + 1 + itemNum * (4 + 4 + 4));
479 data << uint32(rewardData.rdungeonEntry); // Random Dungeon Finished
480 data << uint32(rewardData.sdungeonEntry); // Dungeon Finished
481 data << uint8(rewardData.done);
482 data << uint32(1);
483 data << uint32(rewardData.quest->GetRewOrReqMoney(playerLevel));
484 data << uint32(rewardData.quest->XPValue(playerLevel));
485 data << uint32(0);
486 data << uint32(0);
487 data << uint8(itemNum);
488 if (itemNum)
489 {
490 for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i)
491 if (uint32 itemId = rewardData.quest->RewardItemId[i])
492 {
493 ItemTemplate const* item = sObjectMgr->GetItemTemplate(itemId);
494 data << uint32(itemId);
495 data << uint32(item ? item->DisplayInfoID : 0);
496 data << uint32(rewardData.quest->RewardItemIdCount[i]);
497 }
498 }
499 SendPacket(&data);
500}
@ SMSG_LFG_PLAYER_REWARD
Definition: Opcodes.h:541

◆ SendLfgQueueStatus()

void WorldSession::SendLfgQueueStatus ( lfg::LfgQueueStatusData const &  queueData)

Definition at line 447 of file LFGHandler.cpp.

448{
449 LOG_DEBUG("network", "SMSG_LFG_QUEUE_STATUS [{}] dungeon: {} - waitTime: {} - avgWaitTime: {} - waitTimeTanks: {} - waitTimeHealer: {} - waitTimeDps: {} - queuedTime: {} - tanks: {} - healers: {} - dps: {}",
450 GetPlayer()->GetGUID().ToString(), queueData.dungeonId, queueData.waitTime, queueData.waitTimeAvg, queueData.waitTimeTank,
451 queueData.waitTimeHealer, queueData.waitTimeDps, queueData.queuedTime, queueData.tanks, queueData.healers, queueData.dps);
452 WorldPacket data(SMSG_LFG_QUEUE_STATUS, 4 + 4 + 4 + 4 + 4 + 4 + 1 + 1 + 1 + 4);
453 data << uint32(queueData.dungeonId); // Dungeon
454 data << int32(queueData.waitTimeAvg); // Average Wait time
455 data << int32(queueData.waitTime); // Wait Time
456 data << int32(queueData.waitTimeTank); // Wait Tanks
457 data << int32(queueData.waitTimeHealer); // Wait Healers
458 data << int32(queueData.waitTimeDps); // Wait Dps
459 data << uint8(queueData.tanks); // Tanks needed
460 data << uint8(queueData.healers); // Healers needed
461 data << uint8(queueData.dps); // Dps needed
462 data << uint32(queueData.queuedTime); // Player wait time in queue
463 SendPacket(&data);
464}
@ SMSG_LFG_QUEUE_STATUS
Definition: Opcodes.h:899

◆ SendLfgRoleCheckUpdate()

void WorldSession::SendLfgRoleCheckUpdate ( lfg::LfgRoleCheck const &  pRoleCheck)

Definition at line 385 of file LFGHandler.cpp.

386{
387 lfg::LfgDungeonSet dungeons;
388 if (roleCheck.rDungeonId)
389 dungeons.insert(roleCheck.rDungeonId);
390 else
391 dungeons = roleCheck.dungeons;
392
393 LOG_DEBUG("network", "SMSG_LFG_ROLE_CHECK_UPDATE [{}]", GetPlayer()->GetGUID().ToString());
394 WorldPacket data(SMSG_LFG_ROLE_CHECK_UPDATE, 4 + 1 + 1 + dungeons.size() * 4 + 1 + roleCheck.roles.size() * (8 + 1 + 4 + 1));
395
396 data << uint32(roleCheck.state); // Check result
397 data << uint8(roleCheck.state == lfg::LFG_ROLECHECK_INITIALITING);
398 data << uint8(dungeons.size()); // Number of dungeons
399 if (!dungeons.empty())
400 for (lfg::LfgDungeonSet::iterator it = dungeons.begin(); it != dungeons.end(); ++it)
401 data << uint32(sLFGMgr->GetLFGDungeonEntry(*it)); // Dungeon
402
403 data << uint8(roleCheck.roles.size()); // Players in group
404 if (!roleCheck.roles.empty())
405 {
406 // Leader info MUST be sent 1st :S
407 ObjectGuid guid = roleCheck.leader;
408 uint8 roles = roleCheck.roles.find(guid)->second;
409 data << guid; // Guid
410 data << uint8(roles > 0); // Ready
411 data << uint32(roles); // Roles
413 data << uint8(player ? player->getLevel() : 0); // Level
414
415 for (lfg::LfgRolesMap::const_iterator it = roleCheck.roles.begin(); it != roleCheck.roles.end(); ++it)
416 {
417 if (it->first == roleCheck.leader)
418 continue;
419
420 guid = it->first;
421 roles = it->second;
422 data << guid; // Guid
423 data << uint8(roles > 0); // Ready
424 data << uint32(roles); // Roles
426 data << uint8(player ? player->getLevel() : 0);// Level
427 }
428 }
429 SendPacket(&data);
430}
@ SMSG_LFG_ROLE_CHECK_UPDATE
Definition: Opcodes.h:897
@ LFG_ROLECHECK_INITIALITING
Definition: LFGMgr.h:126

◆ SendLfgRoleChosen()

void WorldSession::SendLfgRoleChosen ( ObjectGuid  guid,
uint8  roles 
)

Definition at line 374 of file LFGHandler.cpp.

375{
376 LOG_DEBUG("network", "SMSG_LFG_ROLE_CHOSEN [{}] guid: [{}] roles: {}", GetPlayer()->GetGUID().ToString(), guid.ToString(), roles);
377
378 WorldPacket data(SMSG_LFG_ROLE_CHOSEN, 8 + 1 + 4);
379 data << guid; // Guid
380 data << uint8(roles > 0); // Ready
381 data << uint32(roles); // Roles
382 SendPacket(&data);
383}
@ SMSG_LFG_ROLE_CHOSEN
Definition: Opcodes.h:729

◆ SendLfgTeleportError()

void WorldSession::SendLfgTeleportError ( uint8  err)

Definition at line 605 of file LFGHandler.cpp.

606{
607 LOG_DEBUG("network", "SMSG_LFG_TELEPORT_DENIED [{}] reason: {}", GetPlayer()->GetGUID().ToString(), err);
609 data << uint32(err); // Error
610 SendPacket(&data);
611}
@ SMSG_LFG_TELEPORT_DENIED
Definition: Opcodes.h:542

◆ SendLfgUpdateParty()

void WorldSession::SendLfgUpdateParty ( lfg::LfgUpdateData const &  updateData)

Definition at line 330 of file LFGHandler.cpp.

331{
332 bool join = false;
333 bool queued = false;
334 uint8 size = uint8(updateData.dungeons.size());
335
336 switch (updateData.updateType)
337 {
338 case lfg::LFG_UPDATETYPE_ADDED_TO_QUEUE: // Rolecheck Success
339 queued = true;
340 [[fallthrough]];
342 join = true;
343 break;
345 join = updateData.state != lfg::LFG_STATE_ROLECHECK && updateData.state != lfg::LFG_STATE_NONE;
346 queued = updateData.state == lfg::LFG_STATE_QUEUED;
347 break;
348 default:
349 break;
350 }
351
352 LOG_DEBUG("lfg", "SMSG_LFG_UPDATE_PARTY {} updatetype: {}",
353 GetPlayerInfo(), updateData.updateType);
354 WorldPacket data(SMSG_LFG_UPDATE_PARTY, 1 + 1 + (size > 0 ? 1 : 0) * (1 + 1 + 1 + 1 + 1 + size * 4 + updateData.comment.length()));
355 data << uint8(updateData.updateType); // Lfg Update type
356 data << uint8(size > 0); // Extra info
357 if (size)
358 {
359 data << uint8(join); // LFG Join
360 data << uint8(queued); // Join the queue
361 data << uint8(0); // unk - Always 0
362 data << uint8(0); // unk - Always 0
363 for (uint8 i = 0; i < 3; ++i)
364 data << uint8(0); // unk - Always 0
365
366 data << uint8(size);
367 for (lfg::LfgDungeonSet::const_iterator it = updateData.dungeons.begin(); it != updateData.dungeons.end(); ++it)
368 data << uint32(*it);
369 data << updateData.comment;
370 }
371 SendPacket(&data);
372}
@ SMSG_LFG_UPDATE_PARTY
Definition: Opcodes.h:902
@ LFG_STATE_ROLECHECK
Definition: LFG.h:72
@ LFG_UPDATETYPE_ADDED_TO_QUEUE
Definition: LFG.h:62
@ LFG_UPDATETYPE_UPDATE_STATUS
Definition: LFG.h:64
@ LFG_UPDATETYPE_PROPOSAL_BEGIN
Definition: LFG.h:63

◆ SendLfgUpdatePlayer()

void WorldSession::SendLfgUpdatePlayer ( lfg::LfgUpdateData const &  updateData)

Definition at line 293 of file LFGHandler.cpp.

294{
295 bool queued = false;
296 uint8 size = uint8(updateData.dungeons.size());
297
298 switch (updateData.updateType)
299 {
302 queued = true;
303 break;
305 queued = updateData.state == lfg::LFG_STATE_QUEUED;
306 break;
307 default:
308 break;
309 }
310
311 LOG_DEBUG("lfg", "SMSG_LFG_UPDATE_PLAYER {} updatetype: {}",
312 GetPlayerInfo(), updateData.updateType);
313 WorldPacket data(SMSG_LFG_UPDATE_PLAYER, 1 + 1 + (size > 0 ? 1 : 0) * (1 + 1 + 1 + 1 + size * 4 + updateData.comment.length()));
314 data << uint8(updateData.updateType); // Lfg Update type
315 data << uint8(size > 0); // Extra info
316 if (size)
317 {
318 data << uint8(queued); // Join the queue
319 data << uint8(0); // unk - Always 0
320 data << uint8(0); // unk - Always 0
321
322 data << uint8(size);
323 for (lfg::LfgDungeonSet::const_iterator it = updateData.dungeons.begin(); it != updateData.dungeons.end(); ++it)
324 data << uint32(*it);
325 data << updateData.comment;
326 }
327 SendPacket(&data);
328}
@ SMSG_LFG_UPDATE_PLAYER
Definition: Opcodes.h:901
@ LFG_UPDATETYPE_JOIN_QUEUE
Definition: LFG.h:56

◆ SendLfgUpdateProposal()

void WorldSession::SendLfgUpdateProposal ( lfg::LfgProposal const &  proposal)

Definition at line 534 of file LFGHandler.cpp.

535{
536 ObjectGuid guid = GetPlayer()->GetGUID();
537 ObjectGuid gguid = proposal.players.find(guid)->second.group;
538 bool silent = !proposal.isNew && gguid == proposal.group;
539 uint32 dungeonEntry = proposal.dungeonId;
540
541 LOG_DEBUG("network", "SMSG_LFG_PROPOSAL_UPDATE [{} state: {}", guid.ToString(), proposal.state);
542
543 // show random dungeon if player selected random dungeon and it's not lfg group
544 if (!silent)
545 {
546 lfg::LfgDungeonSet const& playerDungeons = sLFGMgr->GetSelectedDungeons(guid);
547 if (playerDungeons.find(proposal.dungeonId) == playerDungeons.end())
548 dungeonEntry = (*playerDungeons.begin());
549 }
550
551 dungeonEntry = sLFGMgr->GetLFGDungeonEntry(dungeonEntry);
552
553 WorldPacket data(SMSG_LFG_PROPOSAL_UPDATE, 4 + 1 + 4 + 4 + 1 + 1 + proposal.players.size() * (4 + 1 + 1 + 1 + 1 + 1));
554 data << uint32(dungeonEntry); // Dungeon
555 data << uint8(proposal.state); // Proposal state
556 data << uint32(proposal.id); // Proposal ID
557 data << uint32(proposal.encounters); // encounters done
558 data << uint8(silent); // Show proposal window
559 data << uint8(proposal.players.size()); // Group size
560
561 for (lfg::LfgProposalPlayerContainer::const_iterator it = proposal.players.begin(); it != proposal.players.end(); ++it)
562 {
563 lfg::LfgProposalPlayer const& player = it->second;
564 data << uint32(player.role); // Role
565 data << uint8(it->first == guid); // Self player
566 if (!player.group) // Player not it a group
567 {
568 data << uint8(0); // Not in dungeon
569 data << uint8(0); // Not same group
570 }
571 else
572 {
573 data << uint8(player.group == proposal.group); // In dungeon (silent)
574 data << uint8(player.group == gguid); // Same Group than player
575 }
576 data << uint8(player.accept != lfg::LFG_ANSWER_PENDING);// Answered
577 data << uint8(player.accept == lfg::LFG_ANSWER_AGREE); // Accepted
578 }
579 SendPacket(&data);
580}
@ SMSG_LFG_PROPOSAL_UPDATE
Definition: Opcodes.h:895
uint8 role
Proposed role.
Definition: LFGMgr.h:348
ObjectGuid group
Original group guid. 0 if no original group.
Definition: LFGMgr.h:350
LfgAnswer accept
Accept status (-1 not answer | 0 Not agree | 1 agree)
Definition: LFGMgr.h:349

◆ SendListInventory()

void WorldSession::SendListInventory ( ObjectGuid  guid,
uint32  vendorEntry = 0 
)

Definition at line 992 of file ItemHandler.cpp.

993{
994 LOG_DEBUG("network", "WORLD: Sent SMSG_LIST_INVENTORY");
995
997 if (!vendor)
998 {
999 LOG_DEBUG("network", "WORLD: SendListInventory - Unit ({}) not found or you can not interact with him.", vendorGuid.ToString());
1001 return;
1002 }
1003
1004 // remove fake death
1005 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
1006 {
1008 }
1009
1010 // Stop the npc if moving
1011 if (uint32 pause = vendor->GetMovementTemplate().GetInteractionPauseTimer())
1012 vendor->PauseMovement(pause);
1013 vendor->SetHomePosition(vendor->GetPosition());
1014
1015 SetCurrentVendor(vendorEntry);
1016
1017 VendorItemData const* items = vendorEntry ? sObjectMgr->GetNpcVendorItemList(vendorEntry) : vendor->GetVendorItems();
1018 if (!items)
1019 {
1020 WorldPacket data(SMSG_LIST_INVENTORY, 8 + 1 + 1);
1021 data << vendorGuid;
1022 data << uint8(0); // count == 0, next will be error code
1023 data << uint8(0); // "Vendor has no inventory"
1024 SendPacket(&data);
1025 return;
1026 }
1027
1028 uint8 itemCount = items->GetItemCount();
1029 uint8 count = 0;
1030
1031 WorldPacket data(SMSG_LIST_INVENTORY, 8 + 1 + itemCount * 8 * 4);
1032 data << vendorGuid;
1033
1034 size_t countPos = data.wpos();
1035 data << uint8(count);
1036
1037 float discountMod = _player->GetReputationPriceDiscount(vendor);
1038
1039 for (uint8 slot = 0; slot < itemCount; ++slot)
1040 {
1041 if (VendorItem const* item = items->GetItem(slot))
1042 {
1043 if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(item->item))
1044 {
1045 if (!(itemTemplate->AllowableClass & _player->getClassMask()) && itemTemplate->Bonding == BIND_WHEN_PICKED_UP && !_player->IsGameMaster())
1046 {
1047 continue;
1048 }
1049 // Only display items in vendor lists for the team the
1050 // player is on. If GM on, display all items.
1051 if (!_player->IsGameMaster() && ((itemTemplate->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY && _player->GetTeamId() == TEAM_ALLIANCE) || (itemTemplate->Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY && _player->GetTeamId() == TEAM_HORDE)))
1052 {
1053 continue;
1054 }
1055
1056 // Items sold out are not displayed in list
1057 uint32 leftInStock = !item->maxcount ? 0xFFFFFFFF : vendor->GetVendorItemCurrentCount(item);
1058 if (!_player->IsGameMaster() && !leftInStock)
1059 {
1060 continue;
1061 }
1062
1063 ConditionList conditions = sConditionMgr->GetConditionsForNpcVendorEvent(vendor->GetEntry(), item->item);
1064 if (!sConditionMgr->IsObjectMeetToConditions(_player, vendor, conditions))
1065 {
1066 LOG_DEBUG("network", "SendListInventory: conditions not met for creature entry {} item {}", vendor->GetEntry(), item->item);
1067 continue;
1068 }
1069
1070 // reputation discount
1071 int32 price = item->IsGoldRequired(itemTemplate) ? uint32(floor(itemTemplate->BuyPrice * discountMod)) : 0;
1072
1073 data << uint32(slot + 1); // client expects counting to start at 1
1074 data << uint32(item->item);
1075 data << uint32(itemTemplate->DisplayInfoID);
1076 data << int32(leftInStock);
1077 data << uint32(price);
1078 data << uint32(itemTemplate->MaxDurability);
1079 data << uint32(itemTemplate->BuyCount);
1080 data << uint32(item->ExtendedCost);
1081
1082 if (++count >= MAX_VENDOR_ITEMS)
1083 {
1084 break;
1085 }
1086 }
1087 }
1088 }
1089
1090 if (count == 0)
1091 {
1092 data << uint8(0);
1093 SendPacket(&data);
1094 return;
1095 }
1096
1097 data.put<uint8>(countPos, count);
1098 SendPacket(&data);
1099}
#define sConditionMgr
Definition: ConditionMgr.h:289
std::list< Condition * > ConditionList
Definition: ConditionMgr.h:236
#define MAX_VENDOR_ITEMS
Definition: Creature.h:43
@ ITEM_FLAGS_EXTRA_ALLIANCE_ONLY
Definition: ItemTemplate.h:221
@ ITEM_FLAGS_EXTRA_HORDE_ONLY
Definition: ItemTemplate.h:220
@ SMSG_LIST_INVENTORY
Definition: Opcodes.h:445
VendorItemData const * GetVendorItems() const
Definition: Creature.cpp:2928
uint32 GetVendorItemCurrentCount(VendorItem const *vItem)
Definition: Creature.cpp:2933
VendorItem * GetItem(uint32 slot) const
Definition: CreatureData.h:461
uint8 GetItemCount() const
Definition: CreatureData.h:469
uint32 getClassMask() const
Definition: Unit.h:1425
void SetCurrentVendor(uint32 vendorEntry)
Definition: WorldSession.h:365

◆ SendNameQueryOpcode()

void WorldSession::SendNameQueryOpcode ( ObjectGuid  guid)

Definition at line 31 of file QueryHandler.cpp.

32{
33 CharacterCacheEntry const* playerData = sCharacterCache->GetCharacterCacheByGuid(guid);
34
35 WorldPacket data(SMSG_NAME_QUERY_RESPONSE, (8 + 1 + 1 + 1 + 1 + 1 + 10));
36 data << guid.WriteAsPacked();
37 if (!playerData)
38 {
39 data << uint8(1); // name unknown
40 SendPacket(&data);
41 return;
42 }
43
45
46 data << uint8(0); // name known
47 data << playerData->Name; // played name
48 data << uint8(0); // realm name - only set for cross realm interaction (such as Battlegrounds)
49 data << uint8(player ? player->getRace() : playerData->Race);
50 data << uint8(playerData->Sex);
51 data << uint8(playerData->Class);
52
53 // pussywizard: optimization
54 /*Player* player = ObjectAccessor::FindConnectedPlayer(guid);
55 if (DeclinedName const* names = (player ? player->GetDeclinedNames() : nullptr))
56 {
57 data << uint8(1); // Name is declined
58 for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
59 data << names->name[i];
60 }
61 else*/
62 data << uint8(0); // Name is not declined
63
64 SendPacket(&data);
65}
@ SMSG_NAME_QUERY_RESPONSE
Definition: Opcodes.h:111

◆ SendNotification() [1/2]

void WorldSession::SendNotification ( const char *  format,
  ... 
)

Definition at line 763 of file WorldSession.cpp.

764{
765 if (format)
766 {
767 va_list ap;
768 char szStr[1024];
769 szStr[0] = '\0';
770 va_start(ap, format);
771 vsnprintf(szStr, 1024, format, ap);
772 va_end(ap);
773
774 WorldPacket data(SMSG_NOTIFICATION, (strlen(szStr) + 1));
775 data << szStr;
776 SendPacket(&data);
777 }
778}
@ SMSG_NOTIFICATION
Definition: Opcodes.h:489

◆ SendNotification() [2/2]

void WorldSession::SendNotification ( uint32  string_id,
  ... 
)

Definition at line 780 of file WorldSession.cpp.

781{
782 char const* format = GetAcoreString(string_id);
783 if (format)
784 {
785 va_list ap;
786 char szStr[1024];
787 szStr[0] = '\0';
788 va_start(ap, string_id);
789 vsnprintf(szStr, 1024, format, ap);
790 va_end(ap);
791
792 WorldPacket data(SMSG_NOTIFICATION, (strlen(szStr) + 1));
793 data << szStr;
794 SendPacket(&data);
795 }
796}

◆ SendNotInArenaTeamPacket()

void WorldSession::SendNotInArenaTeamPacket ( uint8  type)

Definition at line 407 of file ArenaTeamHandler.cpp.

408{
409 WorldPacket data(SMSG_ARENA_ERROR, 4 + 1); // 886 - You are not in a %uv%u arena team
410 uint32 unk = 0;
411 data << uint32(unk); // unk(0)
412 if (!unk)
413 data << uint8(type); // team type (2=2v2, 3=3v3, 5=5v5), can be used for custom types...
414 SendPacket(&data);
415}
@ SMSG_ARENA_ERROR
Definition: Opcodes.h:916

◆ SendPacket()

void WorldSession::SendPacket ( WorldPacket const *  packet)

Send a packet to the client.

Definition at line 208 of file WorldSession.cpp.

209{
210 if (packet->GetOpcode() == NULL_OPCODE)
211 {
212 LOG_ERROR("network.opcode", "{} send NULL_OPCODE", GetPlayerInfo());
213 return;
214 }
215
216 if (!m_Socket)
217 return;
218
219#if defined(ACORE_DEBUG)
220 // Code for network use statistic
221 static uint64 sendPacketCount = 0;
222 static uint64 sendPacketBytes = 0;
223
224 static time_t firstTime = GameTime::GetGameTime().count();
225 static time_t lastTime = firstTime; // next 60 secs start time
226
227 static uint64 sendLastPacketCount = 0;
228 static uint64 sendLastPacketBytes = 0;
229
230 time_t cur_time = GameTime::GetGameTime().count();
231
232 if ((cur_time - lastTime) < 60)
233 {
234 sendPacketCount += 1;
235 sendPacketBytes += packet->size();
236
237 sendLastPacketCount += 1;
238 sendLastPacketBytes += packet->size();
239 }
240 else
241 {
242 uint64 minTime = uint64(cur_time - lastTime);
243 uint64 fullTime = uint64(lastTime - firstTime);
244
245 LOG_DEBUG("network", "Send all time packets count: {} bytes: {} avr.count/sec: {} avr.bytes/sec: {} time: {}", sendPacketCount, sendPacketBytes, float(sendPacketCount) / fullTime, float(sendPacketBytes) / fullTime, uint32(fullTime));
246
247 LOG_DEBUG("network", "Send last min packets count: {} bytes: {} avr.count/sec: {} avr.bytes/sec: {}", sendLastPacketCount, sendLastPacketBytes, float(sendLastPacketCount) / minTime, float(sendLastPacketBytes) / minTime);
248
249 lastTime = cur_time;
250 sendLastPacketCount = 1;
251 sendLastPacketBytes = packet->wpos(); // wpos is real written size
252 }
253#endif // !ACORE_DEBUG
254
255 if (!sScriptMgr->CanPacketSend(this, *packet))
256 {
257 return;
258 }
259
260 LOG_TRACE("network.opcode", "S->C: {} {}", GetPlayerInfo(), GetOpcodeNameForLogging(static_cast<OpcodeServer>(packet->GetOpcode())));
261 m_Socket->SendPacket(*packet);
262}
@ NULL_OPCODE
Definition: Opcodes.h:1347

◆ SendPartyResult()

void WorldSession::SendPartyResult ( PartyOperation  operation,
std::string const &  member,
PartyResult  res,
uint32  val = 0 
)

Definition at line 50 of file GroupHandler.cpp.

51{
52 WorldPacket data(SMSG_PARTY_COMMAND_RESULT, 4 + member.size() + 1 + 4 + 4);
53 data << uint32(operation);
54 data << member;
55 data << uint32(res);
56 data << uint32(val); // LFD cooldown related (used with ERR_PARTY_LFG_BOOT_COOLDOWN_S and ERR_PARTY_LFG_BOOT_NOT_ELIGIBLE_S)
57
58 SendPacket(&data);
59}
@ SMSG_PARTY_COMMAND_RESULT
Definition: Opcodes.h:157

◆ SendPetitionQueryOpcode()

void WorldSession::SendPetitionQueryOpcode ( ObjectGuid  petitionguid)

Definition at line 279 of file PetitionsHandler.cpp.

280{
281 Petition const* petition = sPetitionMgr->GetPetition(petitionguid);
282 if (!petition)
283 {
284 LOG_DEBUG("network", "CMSG_PETITION_QUERY failed for petition ({})", petitionguid.ToString());
285 return;
286 }
287
288 uint8 type = petition->petitionType;
289 WorldPacket data(SMSG_PETITION_QUERY_RESPONSE, (4 + 8 + petition->petitionName.size() + 1 + 1 + 4 * 12 + 2 + 10));
290 data << uint32(petitionguid.GetCounter()); // guild/team guid (in Trinity always same as petition low guid
291 data << petition->ownerGuid; // charter owner guid
292 data << petition->petitionName; // name (guild/arena team)
293 data << uint8(0); // some string
294 if (type == GUILD_CHARTER_TYPE)
295 {
296 uint32 needed = sWorld->getIntConfig(CONFIG_MIN_PETITION_SIGNS);
297 data << uint32(needed);
298 data << uint32(needed);
299 data << uint32(0); // bypass client - side limitation, a different value is needed here for each petition
300 }
301 else
302 {
303 data << uint32(type - 1);
304 data << uint32(type - 1);
305 data << uint32(type); // bypass client - side limitation, a different value is needed here for each petition
306 }
307 data << uint32(0); // 5
308 data << uint32(0); // 6
309 data << uint32(0); // 7
310 data << uint32(0); // 8
311 data << uint16(0); // 9 2 bytes field
312 data << uint32(0); // 10
313 data << uint32(0); // 11
314 data << uint32(0); // 13 count of next strings?
315
316 for (int i = 0; i < 10; ++i)
317 data << uint8(0); // some string
318
319 data << uint32(0); // 14
320
321 data << uint32(type != GUILD_CHARTER_TYPE); // 15 0 - guild, 1 - arena team
322
323 SendPacket(&data);
324}
@ SMSG_PETITION_QUERY_RESPONSE
Definition: Opcodes.h:485

◆ SendPetitionShowList()

void WorldSession::SendPetitionShowList ( ObjectGuid  guid)

Definition at line 820 of file PetitionsHandler.cpp.

821{
823 if (!creature)
824 {
825 LOG_DEBUG("network", "WORLD: HandlePetitionShowListOpcode - Unit ({}) not found or you can't interact with him.", guid.ToString());
826 return;
827 }
828
829 WorldPacket data(SMSG_PETITION_SHOWLIST, 8 + 1 + 4 * 6);
830 data << guid; // npc guid
831
832 // For guild default
833 uint32 CharterEntry = GUILD_CHARTER;
834 uint32 CharterDispayID = CHARTER_DISPLAY_ID;
835 uint32 CharterCost = sWorld->getIntConfig(CONFIG_CHARTER_COST_GUILD);
836
837 if (creature->IsTabardDesigner())
838 {
839 sScriptMgr->PetitionShowList(_player, creature, CharterEntry, CharterDispayID, CharterCost);
840
841 data << uint8(1); // count
842 data << uint32(1); // index
843 data << CharterEntry; // charter entry
844 data << CharterDispayID; // charter display id
845 data << CharterCost; // charter cost
846 data << uint32(0); // unknown
847 data << uint32(sWorld->getIntConfig(CONFIG_MIN_PETITION_SIGNS)); // required signs
848 }
849 else
850 {
851 // For 2v2 default
852 CharterEntry = ARENA_TEAM_CHARTER_2v2;
853 CharterDispayID = CHARTER_DISPLAY_ID;
854 CharterCost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_2v2);
855
856 // 2v2
857 data << uint8(3); // count
858 sScriptMgr->PetitionShowList(_player, creature, CharterEntry, CharterDispayID, CharterCost);
859 data << uint32(1); // index
860 data << CharterEntry; // charter entry
861 data << CharterDispayID; // charter display id
862 data << CharterCost; // charter cost
863 data << uint32(2); // unknown
864 data << uint32(2); // required signs?
865
866 // For 3v3 default
867 CharterEntry = ARENA_TEAM_CHARTER_3v3;
868 CharterDispayID = CHARTER_DISPLAY_ID;
869 CharterCost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_3v3);
870
871 // 3v3
872 sScriptMgr->PetitionShowList(_player, creature, CharterEntry, CharterDispayID, CharterCost);
873 data << uint32(2); // index
874 data << CharterEntry; // charter entry
875 data << CharterDispayID; // charter display id
876 data << CharterCost; // charter cost
877 data << uint32(3); // unknown
878 data << uint32(3); // required signs?
879
880 // For 3v3 default
881 CharterEntry = ARENA_TEAM_CHARTER_5v5;
882 CharterDispayID = CHARTER_DISPLAY_ID;
883 CharterCost = sWorld->getIntConfig(CONFIG_CHARTER_COST_ARENA_5v5);
884
885 // 5v5
886 sScriptMgr->PetitionShowList(_player, creature, CharterEntry, CharterDispayID, CharterCost);
887 data << uint32(3); // index
888 data << CharterEntry; // charter entry
889 data << CharterDispayID; // charter display id
890 data << CharterCost; // charter cost
891 data << uint32(5); // unknown
892 data << uint32(5); // required signs?
893 }
894
895 SendPacket(&data);
896 LOG_DEBUG("network", "Sent SMSG_PETITION_SHOWLIST");
897}
#define CHARTER_DISPLAY_ID
Definition: PetitionMgr.h:26
@ SMSG_PETITION_SHOWLIST
Definition: Opcodes.h:474

◆ SendPetNameInvalid()

void WorldSession::SendPetNameInvalid ( uint32  error,
std::string const &  name,
DeclinedName declinedName 
)

Definition at line 1102 of file PetHandler.cpp.

1103{
1104 WorldPacket data(SMSG_PET_NAME_INVALID, 4 + name.size() + 1 + 1);
1105 data << uint32(error);
1106 data << name;
1107 if (declinedName)
1108 {
1109 data << uint8(1);
1110 for (uint32 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
1111 data << declinedName->name[i];
1112 }
1113 else
1114 data << uint8(0);
1115 SendPacket(&data);
1116}
@ SMSG_PET_NAME_INVALID
Definition: Opcodes.h:406

◆ SendPetNameQuery()

void WorldSession::SendPetNameQuery ( ObjectGuid  guid,
uint32  petnumber 
)

Definition at line 613 of file PetHandler.cpp.

614{
616 if (!pet)
617 {
618 WorldPacket data(SMSG_PET_NAME_QUERY_RESPONSE, (4 + 1 + 4 + 1));
619 data << uint32(petnumber);
620 data << uint8(0);
621 data << uint32(0);
622 data << uint8(0);
623 SendPacket(&data);
624 return;
625 }
626
627 std::string name;
629 {
630 // Use localized creature name for the mage pet
632 if (loc_idx != DEFAULT_LOCALE)
633 name = pet->GetNameForLocaleIdx(loc_idx);
634 else
635 name = pet->GetCreatureTemplate()->Name;
636 }
637 else
638 name = pet->GetName();
639
640 WorldPacket data(SMSG_PET_NAME_QUERY_RESPONSE, (4 + 4 + name.size() + 1));
641 data << uint32(petnumber);
642 data << name.c_str();
644
645 if (pet->IsPet() && ((Pet*)pet)->GetDeclinedNames())
646 {
647 data << uint8(1);
648 for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
649 data << ((Pet*)pet)->GetDeclinedNames()->name[i];
650 }
651 else
652 data << uint8(0);
653
654 SendPacket(&data);
655}
@ NPC_WATER_ELEMENTAL_PERM
Definition: PetDefines.h:106
@ SMSG_PET_NAME_QUERY_RESPONSE
Definition: Opcodes.h:113
std::string const & GetNameForLocaleIdx(LocaleConstant locale_idx) const override
Definition: Creature.cpp:3011

◆ SendPlayerAmbiguousNotice()

void WorldSession::SendPlayerAmbiguousNotice ( std::string const &  name)

Definition at line 818 of file ChatHandler.cpp.

819{
820 WorldPacket data(SMSG_CHAT_PLAYER_AMBIGUOUS, name.size() + 1);
821 data << name;
822 SendPacket(&data);
823}
@ SMSG_CHAT_PLAYER_AMBIGUOUS
Definition: Opcodes.h:843

◆ SendPlayerNotFoundNotice()

void WorldSession::SendPlayerNotFoundNotice ( std::string const &  name)

Definition at line 811 of file ChatHandler.cpp.

812{
813 WorldPacket data(SMSG_CHAT_PLAYER_NOT_FOUND, name.size() + 1);
814 data << name;
815 SendPacket(&data);
816}
@ SMSG_CHAT_PLAYER_NOT_FOUND
Definition: Opcodes.h:711

◆ SendQueryTimeResponse()

void WorldSession::SendQueryTimeResponse ( )

Definition at line 83 of file QueryHandler.cpp.

84{
85 auto timeResponse = sWorld->GetNextDailyQuestsResetTime() - GameTime::GetGameTime();
86
88 data << uint32(GameTime::GetGameTime().count());
89 data << uint32(timeResponse.count());
90 SendPacket(&data);
91}
@ SMSG_QUERY_TIME_RESPONSE
Definition: Opcodes.h:493

◆ SendSetPhaseShift()

void WorldSession::SendSetPhaseShift ( uint32  phaseShift)

Definition at line 1634 of file MiscHandler.cpp.

1635{
1637 data << uint32(PhaseShift);
1638 SendPacket(&data);
1639}
@ SMSG_SET_PHASE_SHIFT
Definition: Opcodes.h:1178

◆ SendSetPlayerDeclinedNamesResult()

void WorldSession::SendSetPlayerDeclinedNamesResult ( DeclinedNameResult  result,
ObjectGuid  guid 
)

Definition at line 2630 of file CharacterHandler.cpp.

2631{
2633 data << uint32(result);
2634 data << guid;
2635 SendPacket(&data);
2636}
@ SMSG_SET_PLAYER_DECLINED_NAMES_RESULT
Definition: Opcodes.h:1080

◆ SendShowBank()

void WorldSession::SendShowBank ( ObjectGuid  guid)

Definition at line 191 of file BankHandler.cpp.

192{
193 m_currentBankerGUID = guid;
195 packet.Banker = guid;
196 SendPacket(packet.Write());
197}
WorldPacket const * Write() override
Definition: BankPackets.cpp:44

◆ SendShowMailBox()

void WorldSession::SendShowMailBox ( ObjectGuid  guid)

Definition at line 72 of file NPCHandler.cpp.

73{
75 data << guid;
76 SendPacket(&data);
77}
@ SMSG_SHOW_MAILBOX
Definition: Opcodes.h:693

◆ SendSpiritResurrect()

void WorldSession::SendSpiritResurrect ( )

Definition at line 394 of file NPCHandler.cpp.

395{
396 _player->ResurrectPlayer(0.5f, true);
397
398 _player->DurabilityLossAll(0.25f, true);
399
400 // get corpse nearest graveyard
401 GraveyardStruct const* corpseGrave = nullptr;
402
403 // Search for any graveyards near the player's corpse.
404 corpseGrave = sGraveyard->GetClosestGraveyard(_player, _player->GetTeamId(), _player->HasCorpse());
405
406 // now can spawn bones
408
409 // teleport to nearest from corpse graveyard, if different from nearest to player ghost
410 if (corpseGrave)
411 {
412 GraveyardStruct const* ghostGrave = sGraveyard->GetClosestGraveyard(_player, _player->GetTeamId());
413
414 if (corpseGrave != ghostGrave)
415 _player->TeleportTo(corpseGrave->Map, corpseGrave->x, corpseGrave->y, corpseGrave->z, _player->GetOrientation());
416 // or update at original position
417 //else
418 // _player->UpdateObjectVisibility(); // xinef: not needed, called in ResurrectPlayer
419 }
420 // or update at original position
421 //else
422 // _player->UpdateObjectVisibility(); // xinef: not needed, called in ResurrectPlayer
423}
void DurabilityLossAll(double percent, bool inventory)
Definition: Player.cpp:4601

◆ SendStablePet()

void WorldSession::SendStablePet ( ObjectGuid  guid)

Definition at line 487 of file NPCHandler.cpp.

488{
489 LOG_DEBUG("network", "WORLD: Recv MSG_LIST_STABLED_PETS Send.");
490
491 WorldPacket data(MSG_LIST_STABLED_PETS, 200); // guess size
492 data << guid;
493 size_t wpos = data.wpos();
494 data << uint8(0); // place holder for slot show number
495
496 PetStable* petStable = GetPlayer()->GetPetStable();
497 if (!petStable)
498 {
499 data << uint8(0); // stable slots
500 SendPacket(&data);
501 return;
502 }
503
504 data << uint8(petStable->MaxStabledPets);
505
506 uint8 num = 0; // counter for place holder
507
508 // not let move dead pet in slot
509 if (petStable->CurrentPet)
510 {
511 PetStable::PetInfo const& pet = *petStable->CurrentPet;
512 data << uint32(pet.PetNumber);
513 data << uint32(pet.CreatureId);
514 data << uint32(pet.Level);
515 data << pet.Name; // petname
516 data << uint8(1); // flags: 1 active, 2 inactive
517 ++num;
518 }
519 else
520 {
521 if (PetStable::PetInfo const* pet = petStable->GetUnslottedHunterPet())
522 {
523 data << uint32(pet->PetNumber);
524 data << uint32(pet->CreatureId);
525 data << uint32(pet->Level);
526 data << pet->Name; // petname
527 data << uint8(1); // flags: 1 active, 2 inactive
528 ++num;
529 }
530 }
531
532 for (Optional<PetStable::PetInfo> const& stabledSlot : petStable->StabledPets)
533 {
534 if (stabledSlot)
535 {
536 PetStable::PetInfo const& pet = *stabledSlot;
537 data << uint32(pet.PetNumber);
538 data << uint32(pet.CreatureId);
539 data << uint32(pet.Level);
540 data << pet.Name; // petname
541 data << uint8(2); // flags: 1 active, 2 inactive
542 ++num;
543 }
544 }
545
546 data.put<uint8>(wpos, num); // set real data to placeholder
547 SendPacket(&data);
548}
@ MSG_LIST_STABLED_PETS
Definition: Opcodes.h:653
PetInfo const * GetUnslottedHunterPet() const
Definition: PetDefines.h:225
std::string Name
Definition: PetDefines.h:203

◆ SendStablePetCallback()

void WorldSession::SendStablePetCallback ( ObjectGuid  guid,
PreparedQueryResult  result 
)

◆ SendStableResult()

void WorldSession::SendStableResult ( uint8  guid)

Definition at line 550 of file NPCHandler.cpp.

551{
553 data << uint8(res);
554 SendPacket(&data);
555}
@ SMSG_STABLE_RESULT
Definition: Opcodes.h:657

◆ SendTabardVendorActivate()

void WorldSession::SendTabardVendorActivate ( ObjectGuid  guid)

Definition at line 65 of file NPCHandler.cpp.

66{
68 data << guid;
69 SendPacket(&data);
70}
@ MSG_TABARDVENDOR_ACTIVATE
Definition: Opcodes.h:528

◆ SendTaxiMenu()

void WorldSession::SendTaxiMenu ( Creature unit)

Definition at line 89 of file TaxiHandler.cpp.

90{
91 // find current node
92 uint32 curloc = sObjectMgr->GetNearestTaxiNode(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), unit->GetMapId(), GetPlayer()->GetTeamId());
93
94 if (curloc == 0)
95 return;
96
97 bool lastTaxiCheaterState = GetPlayer()->isTaxiCheater();
98 if (unit->GetEntry() == 29480) GetPlayer()->SetTaxiCheater(true); // Grimwing in Ebon Hold, special case. NOTE: Not perfect, Zul'Aman should not be included according to WoWhead, and I think taxicheat includes it.
99
100 LOG_DEBUG("network", "WORLD: CMSG_TAXINODE_STATUS_QUERY {} ", curloc);
101
102 WorldPacket data(SMSG_SHOWTAXINODES, (4 + 8 + 4 + 8 * 4));
103 data << uint32(1);
104 data << unit->GetGUID();
105 data << uint32(curloc);
106 GetPlayer()->m_taxi.AppendTaximaskTo(data, GetPlayer()->isTaxiCheater());
107 SendPacket(&data);
108
109 LOG_DEBUG("network", "WORLD: Sent SMSG_SHOWTAXINODES");
110
111 GetPlayer()->SetTaxiCheater(lastTaxiCheaterState);
112}
@ SMSG_SHOWTAXINODES
Definition: Opcodes.h:455
bool isTaxiCheater() const
Definition: Player.h:1140
void AppendTaximaskTo(ByteBuffer &data, bool all)
Definition: PlayerTaxi.cpp:116

◆ SendTaxiStatus()

void WorldSession::SendTaxiStatus ( ObjectGuid  guid)

Definition at line 38 of file TaxiHandler.cpp.

39{
40 Player* const player = GetPlayer();
41 Creature* unit = ObjectAccessor::GetCreature(*player, guid);
42 if (!unit || unit->IsHostileTo(player) || !unit->HasNpcFlag(UNIT_NPC_FLAG_FLIGHTMASTER))
43 {
44 LOG_DEBUG("network", "WorldSession::SendTaxiStatus - Unit ({}) not found.", guid.ToString());
45 return;
46 }
47
48 // find taxi node
49 uint32 nearest = sObjectMgr->GetNearestTaxiNode(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), unit->GetMapId(), player->GetTeamId());
50 if (!nearest)
51 {
52 return;
53 }
54
56 data << guid;
57 data << uint8(player->m_taxi.IsTaximaskNodeKnown(nearest) ? 1 : 0);
58 SendPacket(&data);
59 LOG_DEBUG("network", "WORLD: Sent SMSG_TAXINODE_STATUS");
60}
bool IsTaximaskNodeKnown(uint32 nodeidx) const
Definition: PlayerTaxi.h:36
bool HasNpcFlag(NPCFlags flags) const
Definition: Unit.h:1643

◆ SendTimeSync()

void WorldSession::SendTimeSync ( )

Definition at line 1618 of file WorldSession.cpp.

1619{
1622 SendPacket(&data);
1623
1625
1626 // Schedule next sync in 10 sec (except for the 2 first packets, which are spaced by only 5s)
1627 _timeSyncTimer = _timeSyncNextCounter == 0 ? 5000 : 10000;
1629}
@ SMSG_TIME_SYNC_REQ
Definition: Opcodes.h:942

◆ SendTradeStatus()

void WorldSession::SendTradeStatus ( TradeStatus  status)

Definition at line 32 of file TradeHandler.cpp.

33{
34 WorldPacket data;
35
36 switch (status)
37 {
39 data.Initialize(SMSG_TRADE_STATUS, 4 + 8);
40 data << uint32(status);
41 data << uint64(0);
42 break;
44 data.Initialize(SMSG_TRADE_STATUS, 4 + 4);
45 data << uint32(status);
46 data << uint32(0); // added in 2.4.0
47 break;
49 data.Initialize(SMSG_TRADE_STATUS, 4 + 4 + 1 + 4);
50 data << uint32(status);
51 data << uint32(0);
52 data << uint8(0);
53 data << uint32(0);
54 break;
57 data.Initialize(SMSG_TRADE_STATUS, 4 + 1);
58 data << uint32(status);
59 data << uint8(0);
60 break;
61 default:
63 data << uint32(status);
64 break;
65 }
66
67 SendPacket(&data);
68}
@ TRADE_STATUS_ONLY_CONJURED

◆ SendTrainerList() [1/2]

void WorldSession::SendTrainerList ( ObjectGuid  guid)

Definition at line 87 of file NPCHandler.cpp.

88{
89 std::string str = GetAcoreString(LANG_NPC_TAINER_HELLO);
90 SendTrainerList(guid, str);
91}
@ LANG_NPC_TAINER_HELLO
Definition: Language.h:83

◆ SendTrainerList() [2/2]

void WorldSession::SendTrainerList ( ObjectGuid  guid,
std::string const &  strTitle 
)

Definition at line 93 of file NPCHandler.cpp.

94{
95 LOG_DEBUG("network", "WORLD: SendTrainerList");
96
98 if (!unit)
99 {
100 LOG_DEBUG("network", "WORLD: SendTrainerList - Unit ({}) not found or you can not interact with him.", guid.ToString());
101 return;
102 }
103
104 // remove fake death
105 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
107
108 CreatureTemplate const* ci = unit->GetCreatureTemplate();
109
110 if (!ci)
111 {
112 LOG_DEBUG("network", "WORLD: SendTrainerList - ({}) NO CREATUREINFO!", guid.ToString());
113 return;
114 }
115
116 TrainerSpellData const* trainer_spells = unit->GetTrainerSpells();
117 if (!trainer_spells)
118 {
119 LOG_DEBUG("network", "WORLD: SendTrainerList - Training spells not found for creature ({})", guid.ToString());
120 return;
121 }
122
123 WorldPacket data(SMSG_TRAINER_LIST, 8 + 4 + 4 + trainer_spells->spellList.size() * 38 + strTitle.size() + 1);
124 data << guid;
125 data << uint32(trainer_spells->trainerType);
126
127 size_t count_pos = data.wpos();
128 data << uint32(trainer_spells->spellList.size());
129
130 // reputation discount
131 float fDiscountMod = _player->GetReputationPriceDiscount(unit);
132 bool can_learn_primary_prof = GetPlayer()->GetFreePrimaryProfessionPoints() > 0;
133
134 uint32 count = 0;
135 for (TrainerSpellMap::const_iterator itr = trainer_spells->spellList.begin(); itr != trainer_spells->spellList.end(); ++itr)
136 {
137 TrainerSpell const* tSpell = &itr->second;
138
139 bool valid = true;
140 bool primary_prof_first_rank = false;
141 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
142 {
143 if (!tSpell->learnedSpell[i])
144 continue;
146 {
147 valid = false;
148 break;
149 }
150 SpellInfo const* learnedSpellInfo = sSpellMgr->GetSpellInfo(tSpell->learnedSpell[i]);
151 if (learnedSpellInfo && learnedSpellInfo->IsPrimaryProfessionFirstRank())
152 primary_prof_first_rank = true;
153 }
154
155 if (!valid)
156 continue;
157
158 if (tSpell->reqSpell && !_player->HasSpell(tSpell->reqSpell))
159 {
160 continue;
161 }
162
164
165 data << uint32(tSpell->spell); // learned spell (or cast-spell in profession case)
166 data << uint8(state == TRAINER_SPELL_GREEN_DISABLED ? TRAINER_SPELL_GREEN : state);
167 data << uint32(floor(tSpell->spellCost * fDiscountMod));
168
169 data << uint32(primary_prof_first_rank && can_learn_primary_prof ? 1 : 0);
170 // primary prof. learn confirmation dialog
171 data << uint32(primary_prof_first_rank ? 1 : 0); // must be equal prev. field to have learn button in enabled state
172 data << uint8(tSpell->reqLevel);
173 data << uint32(tSpell->reqSkill);
174 data << uint32(tSpell->reqSkillValue);
175 //prev + req or req + 0
176 uint8 maxReq = 0;
177 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
178 {
179 if (!tSpell->learnedSpell[i])
180 continue;
181 if (uint32 prevSpellId = sSpellMgr->GetPrevSpellInChain(tSpell->learnedSpell[i]))
182 {
183 data << uint32(prevSpellId);
184 ++maxReq;
185 }
186 if (maxReq == 3)
187 break;
188 SpellsRequiringSpellMapBounds spellsRequired = sSpellMgr->GetSpellsRequiredForSpellBounds(tSpell->learnedSpell[i]);
189 for (SpellsRequiringSpellMap::const_iterator itr2 = spellsRequired.first; itr2 != spellsRequired.second && maxReq < 3; ++itr2)
190 {
191 data << uint32(itr2->second);
192 ++maxReq;
193 }
194 if (maxReq == 3)
195 break;
196 }
197 while (maxReq < 3)
198 {
199 data << uint32(0);
200 ++maxReq;
201 }
202
203 ++count;
204 }
205
206 data << strTitle;
207
208 data.put<uint32>(count_pos, count);
209 SendPacket(&data);
210}
TrainerSpellState
Definition: Player.h:213
@ TRAINER_SPELL_GREEN_DISABLED
Definition: Player.h:217
std::pair< SpellsRequiringSpellMap::const_iterator, SpellsRequiringSpellMap::const_iterator > SpellsRequiringSpellMapBounds
Definition: SpellMgr.h:563
@ SMSG_TRAINER_LIST
Definition: Opcodes.h:463
uint32 reqSkillValue
Definition: CreatureData.h:506
uint32 learnedSpell[3]
Definition: CreatureData.h:508
uint32 reqSkill
Definition: CreatureData.h:505
uint32 reqLevel
Definition: CreatureData.h:507
TrainerSpellMap spellList
Definition: CreatureData.h:522
bool IsSpellFitByClassAndRace(uint32 spell_id) const
Definition: Player.cpp:12074
uint32 GetFreePrimaryProfessionPoints() const
Definition: Player.h:1722
bool IsPrimaryProfessionFirstRank() const
Definition: SpellInfo.cpp:966

◆ SendTutorialsData()

void WorldSession::SendTutorialsData ( )

Definition at line 937 of file WorldSession.cpp.

938{
940 for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
941 data << m_Tutorials[i];
942 SendPacket(&data);
943}
@ SMSG_TUTORIAL_FLAGS
Definition: Opcodes.h:283

◆ SendUpdateTrade()

void WorldSession::SendUpdateTrade ( bool  trader_data = true)

Definition at line 82 of file TradeHandler.cpp.

83{
84 TradeData* view_trade = trader_data ? _player->GetTradeData()->GetTraderData() : _player->GetTradeData();
85
86 WorldPacket data(SMSG_TRADE_STATUS_EXTENDED, 1 + 4 + 4 + 4 + 4 + 4 + 7 * (1 + 4 + 4 + 4 + 4 + 8 + 4 + 4 + 4 + 4 + 8 + 4 + 4 + 4 + 4 + 4 + 4));
87 data << uint8(trader_data); // 1 means traders data, 0 means own
88 data << uint32(0); // added in 2.4.0, this value must be equal to value from TRADE_STATUS_OPEN_WINDOW status packet (different value for different players to block multiple trades?)
89 data << uint32(TRADE_SLOT_COUNT); // trade slots count/number?, = next field in most cases
90 data << uint32(TRADE_SLOT_COUNT); // trade slots count/number?, = prev field in most cases
91 data << uint32(view_trade->GetMoney()); // trader gold
92 data << uint32(view_trade->GetSpell()); // spell casted on lowest slot item
93
94 for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i)
95 {
96 data << uint8(i); // trade slot number, if not specified, then end of packet
97
98 if (Item* item = view_trade->GetItem(TradeSlots(i)))
99 {
100 data << uint32(item->GetTemplate()->ItemId); // entry
101 data << uint32(item->GetTemplate()->DisplayInfoID);// display id
102 data << uint32(item->GetCount()); // stack count
103 // wrapped: hide stats but show giftcreator name
104 data << uint32(item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_WRAPPED) ? 1 : 0);
105 data << item->GetGuidValue(ITEM_FIELD_GIFTCREATOR);
106 // perm. enchantment and gems
107 data << uint32(item->GetEnchantmentId(PERM_ENCHANTMENT_SLOT));
108 for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT + MAX_GEM_SOCKETS; ++enchant_slot)
109 data << uint32(item->GetEnchantmentId(EnchantmentSlot(enchant_slot)));
110 // creator
111 data << item->GetGuidValue(ITEM_FIELD_CREATOR);
112 data << uint32(item->GetSpellCharges()); // charges
113 data << uint32(item->GetItemSuffixFactor()); // SuffixFactor
114 data << int32(item->GetItemRandomPropertyId()); // random properties id
115 data << uint32(item->GetTemplate()->LockID); // lock id
116 // max durability
117 data << uint32(item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY));
118 // durability
119 data << uint32(item->GetUInt32Value(ITEM_FIELD_DURABILITY));
120 }
121 else
122 {
123 for (uint8 j = 0; j < 18; ++j)
124 data << uint32(0);
125 }
126 }
127 SendPacket(&data);
128}
@ PERM_ENCHANTMENT_SLOT
Definition: Item.h:163
@ SMSG_TRADE_STATUS_EXTENDED
Definition: Opcodes.h:319
TradeData * GetTraderData() const
Definition: TradeData.cpp:21

◆ SendWrongFactionNotice()

void WorldSession::SendWrongFactionNotice ( )

Definition at line 825 of file ChatHandler.cpp.

826{
828 SendPacket(&data);
829}
@ SMSG_CHAT_WRONG_FACTION
Definition: Opcodes.h:567

◆ SetAccountData()

void WorldSession::SetAccountData ( AccountDataType  type,
time_t  tm,
std::string const &  data 
)

Definition at line 882 of file WorldSession.cpp.

883{
884 uint32 id = 0;
886 if ((1 << type) & GLOBAL_CACHE_MASK)
887 {
888 id = GetAccountId();
889 index = CHAR_REP_ACCOUNT_DATA;
890 }
891 else
892 {
893 // _player can be nullptr and packet received after logout but m_GUID still store correct guid
894 if (!m_GUIDLow)
895 return;
896
897 id = m_GUIDLow;
899 }
900
901 CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(index);
902 stmt->SetData(0, id);
903 stmt->SetData(1, type);
904 stmt->SetData(2, uint32(tm));
905 stmt->SetData(3, data);
906 CharacterDatabase.Execute(stmt);
907
908 m_accountData[type].Time = tm;
909 m_accountData[type].Data = data;
910}
CharacterDatabaseStatements
@ CHAR_REP_PLAYER_ACCOUNT_DATA
@ CHAR_REP_ACCOUNT_DATA

◆ SetCalendarEventCreationCooldown()

void WorldSession::SetCalendarEventCreationCooldown ( time_t  cooldown)
inline

Definition at line 528 of file WorldSession.h.

528{ _calendarEventCreationCooldown = cooldown; }

◆ SetCurrentVendor()

void WorldSession::SetCurrentVendor ( uint32  vendorEntry)
inline

Definition at line 365 of file WorldSession.h.

365{ m_currentVendorEntry = vendorEntry; }

◆ SetInQueue()

void WorldSession::SetInQueue ( bool  state)
inline

Session in auth.queue currently.

Definition at line 379 of file WorldSession.h.

379{ m_inQueue = state; }

◆ SetKicked()

void WorldSession::SetKicked ( bool  val)
inline

Definition at line 1067 of file WorldSession.h.

1067{ _kicked = val; }

◆ SetLatency()

void WorldSession::SetLatency ( uint32  latency)
inline

Definition at line 500 of file WorldSession.h.

500{ m_latency = latency; }

◆ SetLogoutStartTime()

void WorldSession::SetLogoutStartTime ( time_t  requestTime)
inline

Engage the logout process for the user.

Definition at line 385 of file WorldSession.h.

386 {
387 _logoutTime = requestTime;
388 }

◆ SetOfflineTime()

void WorldSession::SetOfflineTime ( uint32  time)
inline

Definition at line 1064 of file WorldSession.h.

1064{ _offlineTime = time; }

◆ SetPlayer()

void WorldSession::SetPlayer ( Player player)

Definition at line 1266 of file WorldSession.cpp.

1267{
1268 _player = player;
1269 if (_player)
1271}

◆ SetSecurity()

void WorldSession::SetSecurity ( AccountTypes  security)
inline

Definition at line 368 of file WorldSession.h.

368{ _security = security; }

◆ SetShouldSetOfflineInDB()

void WorldSession::SetShouldSetOfflineInDB ( bool  val)
inline

Definition at line 1068 of file WorldSession.h.

1068{ _shouldSetOfflineInDB = val; }

◆ SetTotalTime()

void WorldSession::SetTotalTime ( uint32  TotalTime)
inline

Definition at line 373 of file WorldSession.h.

373{ m_total_time = TotalTime; }

◆ SetTutorialInt()

void WorldSession::SetTutorialInt ( uint8  index,
uint32  value 
)
inline

Definition at line 457 of file WorldSession.h.

458 {
459 if (m_Tutorials[index] != value)
460 {
461 m_Tutorials[index] = value;
462 m_TutorialsChanged = true;
463 }
464 }

◆ ShouldLogOut()

bool WorldSession::ShouldLogOut ( time_t  currTime) const
inline

Is logout cooldown expired?

Definition at line 391 of file WorldSession.h.

392 {
393 return (_logoutTime > 0 && currTime >= _logoutTime + 20);
394 }

◆ Update()

bool WorldSession::Update ( uint32  diff,
PacketFilter updater 
)

Update the WorldSession (triggered by World update)

  • Before we process anything: If necessary, kick the player because the client didn't send anything for too long (or they've been idling in character select)
  • Retrieve packets from the receive queue and call the appropriate handlers not process packets if socket already closed

Delete packet after processing by default

Definition at line 290 of file WorldSession.cpp.

291{
296 m_Socket->CloseSocket();
297
298 if (updater.ProcessUnsafe())
299 UpdateTimeOutTime(diff);
300
302
305 WorldPacket* packet = nullptr;
306
308 bool deletePacket = true;
309 std::vector<WorldPacket*> requeuePackets;
310 uint32 processedPackets = 0;
311 time_t currentTime = GameTime::GetGameTime().count();
312
313 constexpr uint32 MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE = 150;
314
315 while (m_Socket && _recvQueue.next(packet, updater))
316 {
317 OpcodeClient opcode = static_cast<OpcodeClient>(packet->GetOpcode());
318 ClientOpcodeHandler const* opHandle = opcodeTable[opcode];
319
320 METRIC_DETAILED_TIMER("worldsession_update_opcode_time", METRIC_TAG("opcode", opHandle->Name));
321
322 try
323 {
324 switch (opHandle->Status)
325 {
326 case STATUS_LOGGEDIN:
327 if (!_player)
328 {
329 // pussywizard: such packets were sent to do something for a character that has already logged out, skip them
330 }
331 else if (!_player->IsInWorld())
332 {
333 // pussywizard: such packets may do something important and the player is just being teleported, move to the end of the queue
334 // pussywizard: previously such were skipped, so leave it as it is xD proper code below if we wish to change that
335
336 // pussywizard: requeue only important packets not related to maps (PROCESS_THREADUNSAFE)
337 /*if (opHandle.packetProcessing == PROCESS_THREADUNSAFE)
338 {
339 if (!firstDelayedPacket)
340 firstDelayedPacket = packet;
341 deletePacket = false;
342 QueuePacket(packet);
343 }*/
344 }
345 else if (_player->IsInWorld() && AntiDOS.EvaluateOpcode(*packet, currentTime))
346 {
347 if (!sScriptMgr->CanPacketReceive(this, *packet))
348 {
349 break;
350 }
351
352 opHandle->Call(this, *packet);
353 LogUnprocessedTail(packet);
354 }
355 else
356 processedPackets = MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE; // break out of packet processing loop
357 break;
358 case STATUS_TRANSFER:
359 if (_player && !_player->IsInWorld() && AntiDOS.EvaluateOpcode(*packet, currentTime))
360 {
361 if (!sScriptMgr->CanPacketReceive(this, *packet))
362 {
363 break;
364 }
365
366 opHandle->Call(this, *packet);
367 LogUnprocessedTail(packet);
368 }
369 else
370 processedPackets = MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE; // break out of packet processing loop
371 break;
372 case STATUS_AUTHED:
373 if (m_inQueue) // prevent cheating
374 break;
375
376 if (AntiDOS.EvaluateOpcode(*packet, currentTime))
377 {
378 if (!sScriptMgr->CanPacketReceive(this, *packet))
379 {
380 break;
381 }
382
383 opHandle->Call(this, *packet);
384 LogUnprocessedTail(packet);
385 }
386 else
387 processedPackets = MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE; // break out of packet processing loop
388 break;
389 case STATUS_NEVER:
390 LOG_ERROR("network.opcode", "Received not allowed opcode {} from {}",
391 GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), GetPlayerInfo());
392 break;
393 case STATUS_UNHANDLED:
394 LOG_DEBUG("network.opcode", "Received not handled opcode {} from {}",
395 GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), GetPlayerInfo());
396 break;
397 }
398 }
400 {
401 LOG_ERROR("network", "{} sent {} with an invalid link:\n{}", GetPlayerInfo(),
402 GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), ihe.GetInvalidValue());
403
405 {
406 KickPlayer("WorldSession::Update Invalid chat link");
407 }
408 }
410 {
411 LOG_ERROR("network", "{} sent {} which illegally contained a hyperlink:\n{}", GetPlayerInfo(),
412 GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), ihe.GetInvalidValue());
413
415 {
416 KickPlayer("WorldSession::Update Illegal chat link");
417 }
418 }
420 {
421 LOG_ERROR("network", "PacketArrayMaxCapacityException: {} while parsing {} from {}.",
422 pamce.what(), GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())), GetPlayerInfo());
423 }
424 catch (ByteBufferException const&)
425 {
426 LOG_ERROR("network", "WorldSession::Update ByteBufferException occured while parsing a packet (opcode: {}) from client {}, accountid={}. Skipped packet.", packet->GetOpcode(), GetRemoteAddress(), GetAccountId());
427 if (sLog->ShouldLog("network", LogLevel::LOG_LEVEL_DEBUG))
428 {
429 LOG_DEBUG("network", "Dumping error causing packet:");
430 packet->hexlike();
431 }
432 }
433
434 if (deletePacket)
435 delete packet;
436
437 deletePacket = true;
438
439 processedPackets++;
440
441 //process only a max amout of packets in 1 Update() call.
442 //Any leftover will be processed in next update
443 if (processedPackets > MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE)
444 break;
445 }
446
447 _recvQueue.readd(requeuePackets.begin(), requeuePackets.end());
448
449 METRIC_VALUE("processed_packets", processedPackets);
450 METRIC_VALUE("addon_messages", _addonMessageReceiveCount.load());
452
453 if (!updater.ProcessUnsafe()) // <=> updater is of type MapSessionFilter
454 {
455 // Send time sync packet every 10s.
456 if (_timeSyncTimer > 0)
457 {
458 if (diff >= _timeSyncTimer)
459 {
460 SendTimeSync();
461 }
462 else
463 {
464 _timeSyncTimer -= diff;
465 }
466 }
467 }
468
470
471 //check if we are safe to proceed with logout
472 //logout procedure should happen only in World::UpdateSessions() method!!!
473 if (updater.ProcessUnsafe())
474 {
475 if (m_Socket && m_Socket->IsOpen() && _warden)
476 {
477 _warden->Update(diff);
478 }
479
480 if (ShouldLogOut(currentTime) && !m_playerLoading)
481 {
482 LogoutPlayer(true);
483 }
484
485 if (m_Socket && !m_Socket->IsOpen())
486 {
487 if (GetPlayer() && _warden)
488 _warden->Update(diff);
489
490 m_Socket = nullptr;
491 }
492
493 if (!m_Socket)
494 {
495 return false;
496 }
497 }
498
499 return true;
500}
#define METRIC_DETAILED_TIMER(category,...)
Definition: Metric.h:221
#define METRIC_VALUE(category, value,...)
Definition: Metric.h:195
#define METRIC_TAG(name, value)
Definition: Metric.h:161
@ STATUS_AUTHED
Definition: AuthSession.h:43
@ CONFIG_CLOSE_IDLE_CONNECTIONS
Definition: IWorld.h:158
char const * Name
Definition: Opcodes.h:1379
OpcodeTable opcodeTable
Definition: Opcodes.cpp:51
SessionStatus Status
Definition: Opcodes.h:1380
virtual void Call(WorldSession *session, WorldPacket &packet) const =0
@ STATUS_LOGGEDIN
Definition: Opcodes.h:1357
@ STATUS_TRANSFER
Definition: Opcodes.h:1358
@ STATUS_NEVER
Definition: Opcodes.h:1359
@ STATUS_UNHANDLED
Definition: Opcodes.h:1360
void readd(Iterator begin, Iterator end)
Adds items back to front of the queue.
Definition: LockedQueue.h:56
std::string const & GetInvalidValue() const
virtual bool ProcessUnsafe() const
Definition: WorldSession.h:237
void UpdateTimeOutTime(uint32 diff)
Definition: WorldSession.h:503
void LogUnprocessedTail(WorldPacket *packet)
Logging helper for unexpected opcodes.
void ProcessQueryCallbacks()
void HandleTeleportTimeout(bool updateInSessions)
bool ShouldLogOut(time_t currTime) const
Is logout cooldown expired?
Definition: WorldSession.h:391
bool IsConnectionIdle() const
Definition: WorldSession.h:517
bool EvaluateOpcode(WorldPacket &p, time_t time) const
char const * what() const noexcept override
Definition: ByteBuffer.h:36

◆ UpdateTimeOutTime()

void WorldSession::UpdateTimeOutTime ( uint32  diff)
inline

Definition at line 503 of file WorldSession.h.

504 {
505 if (time_t(diff) > m_timeOutTime)
506 m_timeOutTime = 0;
507 else
508 m_timeOutTime -= diff;
509 }

◆ ValidateHyperlinksAndMaybeKick()

bool WorldSession::ValidateHyperlinksAndMaybeKick ( std::string_view  str)

Definition at line 735 of file WorldSession.cpp.

736{
738 return true;
739
740 LOG_ERROR("network", "Player {}{} sent a message with an invalid link:\n%.*s", GetPlayer()->GetName(),
741 GetPlayer()->GetGUID().ToString(), STRING_VIEW_FMT_ARG(str));
742
744 KickPlayer("WorldSession::ValidateHyperlinksAndMaybeKick Invalid chat link");
745
746 return false;
747}
bool AC_GAME_API CheckAllLinks(std::string_view str)
Definition: Hyperlinks.cpp:378

◆ WriteMovementInfo()

void WorldSession::WriteMovementInfo ( WorldPacket data,
MovementInfo mi 
)

Definition at line 1078 of file WorldSession.cpp.

1079{
1080 *data << mi->guid.WriteAsPacked();
1081
1082 *data << mi->flags;
1083 *data << mi->flags2;
1084 *data << mi->time;
1085 *data << mi->pos.PositionXYZOStream();
1086
1088 {
1089 *data << mi->transport.guid.WriteAsPacked();
1090
1091 *data << mi->transport.pos.PositionXYZOStream();
1092 *data << mi->transport.time;
1093 *data << mi->transport.seat;
1094
1096 *data << mi->transport.time2;
1097 }
1098
1100 *data << mi->pitch;
1101
1102 *data << mi->fallTime;
1103
1105 {
1106 *data << mi->jump.zspeed;
1107 *data << mi->jump.sinAngle;
1108 *data << mi->jump.cosAngle;
1109 *data << mi->jump.xyspeed;
1110 }
1111
1113 *data << mi->splineElevation;
1114}

Friends And Related Function Documentation

◆ World

friend class World
friend

Definition at line 1087 of file WorldSession.h.

Member Data Documentation

◆ _accountId

uint32 WorldSession::_accountId
private

Definition at line 1146 of file WorldSession.h.

◆ _accountName

std::string WorldSession::_accountName
private

Definition at line 1147 of file WorldSession.h.

◆ _addonMessageReceiveCount

std::atomic<uint32> WorldSession::_addonMessageReceiveCount
private

Definition at line 1180 of file WorldSession.h.

◆ _calendarEventCreationCooldown

time_t WorldSession::_calendarEventCreationCooldown
private

Definition at line 1177 of file WorldSession.h.

◆ _kicked

bool WorldSession::_kicked
private

Definition at line 1174 of file WorldSession.h.

◆ _lastAuctionListItemsMSTime

uint32 WorldSession::_lastAuctionListItemsMSTime

Definition at line 1059 of file WorldSession.h.

◆ _lastAuctionListOwnerItemsMSTime

uint32 WorldSession::_lastAuctionListOwnerItemsMSTime

Definition at line 1060 of file WorldSession.h.

◆ _legitCharacters

GuidSet WorldSession::_legitCharacters
private

Definition at line 1137 of file WorldSession.h.

◆ _logoutTime

time_t WorldSession::_logoutTime
private

Definition at line 1156 of file WorldSession.h.

◆ _offlineTime

uint32 WorldSession::_offlineTime
private

Definition at line 1173 of file WorldSession.h.

◆ _pendingTimeSyncRequests

std::map<uint32, uint32> WorldSession::_pendingTimeSyncRequests
private

Definition at line 1186 of file WorldSession.h.

◆ _player

Player* WorldSession::_player
private

Definition at line 1140 of file WorldSession.h.

◆ _queryHolderProcessor

AsyncCallbackProcessor<SQLQueryHolderCallback> WorldSession::_queryHolderProcessor
private

Definition at line 1085 of file WorldSession.h.

◆ _queryProcessor

QueryCallbackProcessor WorldSession::_queryProcessor
private

Definition at line 1083 of file WorldSession.h.

◆ _recvQueue

LockedQueue<WorldPacket*> WorldSession::_recvQueue
private

Definition at line 1170 of file WorldSession.h.

◆ _security

AccountTypes WorldSession::_security
private

Definition at line 1144 of file WorldSession.h.

◆ _shouldSetOfflineInDB

bool WorldSession::_shouldSetOfflineInDB
private

Definition at line 1175 of file WorldSession.h.

◆ _skipQueue

bool WorldSession::_skipQueue
private

Definition at line 1145 of file WorldSession.h.

◆ _timeSyncClockDelta

int64 WorldSession::_timeSyncClockDelta
private

Definition at line 1183 of file WorldSession.h.

◆ _timeSyncClockDeltaQueue

CircularBuffer<std::pair<int64, uint32> > WorldSession::_timeSyncClockDeltaQueue
private

Definition at line 1182 of file WorldSession.h.

◆ _timeSyncNextCounter

uint32 WorldSession::_timeSyncNextCounter
private

Definition at line 1187 of file WorldSession.h.

◆ _timeSyncTimer

uint32 WorldSession::_timeSyncTimer
private

Definition at line 1188 of file WorldSession.h.

◆ _transactionCallbacks

AsyncCallbackProcessor<TransactionCallback> WorldSession::_transactionCallbacks
private

Definition at line 1084 of file WorldSession.h.

◆ _warden

std::unique_ptr<Warden> WorldSession::_warden
private

Definition at line 1154 of file WorldSession.h.

◆ AntiDOS

class WorldSession::DosProtection WorldSession::AntiDOS
protected

◆ isRecruiter

bool WorldSession::isRecruiter
private

Definition at line 1169 of file WorldSession.h.

◆ m_accountData

AccountData WorldSession::m_accountData[NUM_ACCOUNT_DATA_TYPES]
private

Definition at line 1164 of file WorldSession.h.

◆ m_addonsList

AddonsList WorldSession::m_addonsList
private

Definition at line 1167 of file WorldSession.h.

◆ m_Address

std::string WorldSession::m_Address
private

Definition at line 1142 of file WorldSession.h.

◆ m_currentBankerGUID

ObjectGuid WorldSession::m_currentBankerGUID
private

Definition at line 1172 of file WorldSession.h.

◆ m_currentVendorEntry

uint32 WorldSession::m_currentVendorEntry
private

Definition at line 1171 of file WorldSession.h.

◆ m_expansion

uint8 WorldSession::m_expansion
private

Definition at line 1148 of file WorldSession.h.

◆ m_GUIDLow

ObjectGuid::LowType WorldSession::m_GUIDLow
private

Definition at line 1139 of file WorldSession.h.

◆ m_inQueue

bool WorldSession::m_inQueue
private

Definition at line 1157 of file WorldSession.h.

◆ m_latency

std::atomic<uint32> WorldSession::m_latency
private

Definition at line 1163 of file WorldSession.h.

◆ m_muteTime

time_t WorldSession::m_muteTime

Definition at line 492 of file WorldSession.h.

◆ m_playerLoading

bool WorldSession::m_playerLoading
private

Definition at line 1158 of file WorldSession.h.

◆ m_playerLogout

bool WorldSession::m_playerLogout
private

Definition at line 1159 of file WorldSession.h.

◆ m_playerSave

bool WorldSession::m_playerSave
private

Definition at line 1160 of file WorldSession.h.

◆ m_sessionDbcLocale

LocaleConstant WorldSession::m_sessionDbcLocale
private

Definition at line 1161 of file WorldSession.h.

◆ m_sessionDbLocaleIndex

LocaleConstant WorldSession::m_sessionDbLocaleIndex
private

Definition at line 1162 of file WorldSession.h.

◆ m_Socket

std::shared_ptr<WorldSocket> WorldSession::m_Socket
private

Definition at line 1141 of file WorldSession.h.

◆ m_timeOutTime

std::atomic<time_t> WorldSession::m_timeOutTime

Definition at line 502 of file WorldSession.h.

◆ m_total_time

uint32 WorldSession::m_total_time
private

Definition at line 1149 of file WorldSession.h.

◆ m_Tutorials

uint32 WorldSession::m_Tutorials[MAX_ACCOUNT_TUTORIAL_VALUES]
private

Definition at line 1165 of file WorldSession.h.

◆ m_TutorialsChanged

bool WorldSession::m_TutorialsChanged
private

Definition at line 1166 of file WorldSession.h.

◆ recruiterId

uint32 WorldSession::recruiterId
private

Definition at line 1168 of file WorldSession.h.


The documentation for this class was generated from the following files: